home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.043 / samba-1
Text File  |  1995-11-07  |  180KB  |  6,168 lines

  1. diff -u -r --new-file last-version/docs/smb.conf.5 samba-1.9.14p3/docs/smb.conf.5
  2. --- last-version/docs/smb.conf.5    Sun Sep 17 10:28:23 1995
  3. +++ samba-1.9.14p3/docs/smb.conf.5    Sun Nov  5 11:35:38 1995
  4. @@ -1510,7 +1510,7 @@
  5.  
  6.  The string can contain the macros %o and %n which are substituted for
  7.  the old and new passwords respectively. It can aso contain the
  8. -standard macros \n \r \t and \s to give line-feed, carriage-return,
  9. +standard macros \\n \\r \\t and \\s to give line-feed, carriage-return,
  10.  tab and space.
  11.  
  12.  The string can also contain a * which matches any sequence of
  13. @@ -1524,11 +1524,11 @@
  14.  then no string is expected.
  15.  
  16.  .B Example:
  17. -    passwd chat = "*Enter OLD password*" %o\n "*Enter NEW password*" %n\n \
  18. -                      "*Reenter NEW password*" %n\n "*Password changed*"
  19. +    passwd chat = "*Enter OLD password*" %o\\n "*Enter NEW password*" %n\\n \\
  20. +                      "*Reenter NEW password*" %n\\n "*Password changed*"
  21.  
  22.  .B Default:
  23. -    passwd chat = *old*password* %o\n *new*password* %n\n *new*password* %n\n *changed*
  24. +    passwd chat = *old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*
  25.  
  26.  .SS passwd program (G)
  27.  The name of a program that can be used to set user passwords.
  28. diff -u -r --new-file last-version/source/Makefile samba-1.9.14p3/source/Makefile
  29. --- last-version/source/Makefile    Thu Sep 21 20:24:34 1995
  30. +++ samba-1.9.14p3/source/Makefile    Tue Nov  7 22:58:21 1995
  31. @@ -422,7 +422,8 @@
  32.  CFLAGS  = $(CFLAGS5) $(DCE_FLAGS) $(DES_FLAGS) $(PASSWD_FLAGS) $(VTP_FLAGS)
  33.  LIBS = $(LIBS1) $(LIBSM) $(DCE_LIBS) $(DES_LIB)
  34.  
  35. -PROGS = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd
  36. +PROGS1 = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd 
  37. +PROGS = $(PROGS1) nmbd2
  38.  SCRIPTS = smbtar
  39.  
  40.  all : CHECK $(PROGS)
  41. @@ -436,8 +437,10 @@
  42.  INCLUDES2 = pcap.h trans2.h reply.h
  43.  INCLUDES = $(INCLUDES1) $(INCLUDES2)
  44.  
  45. -UTILOBJ = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
  46. -PARAMOBJ = $(UTILOBJ) loadparm.o params.o pcap.o access.o username.o ufc.o smbpass.o
  47. +UTILOBJ1 = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
  48. +UTILOBJ = $(UTILOBJ1) md4.o
  49. +PARAMOBJ1 = $(UTILOBJ) loadparm.o params.o pcap.o access.o username.o
  50. +PARAMOBJ = $(PARAMOBJ1) ufc.o smbpass.o 
  51.  SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
  52.  SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o
  53.  SMBDOBJ = $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ)
  54. @@ -457,9 +460,13 @@
  55.      @echo Linking smbrun
  56.      @$(CC) $(CFLAGS) -o smbrun smbrun.o $(LIBS)
  57.  
  58. -nmbd: nameserv.o $(UTILOBJ) 
  59. +nmbd: nameserv.o $(UTILOBJ)  
  60.      @echo Linking nmbd
  61.      @$(CC) $(CFLAGS) -o nmbd nameserv.o $(UTILOBJ) $(LIBS)
  62. +
  63. +nmbd2: nameserv2.o nmblib.o $(UTILOBJ) 
  64. +    @echo Linking nmbd2
  65. +    @$(CC) $(CFLAGS) -o nmbd2 nameserv2.o nmblib.o $(UTILOBJ) $(LIBS)
  66.  
  67.  smbclient: client.o clitar.o $(UTILOBJ) 
  68.      @echo Linking smbclient
  69. diff -u -r --new-file last-version/source/change-log samba-1.9.14p3/source/change-log
  70. --- last-version/source/change-log    Sat Nov  4 23:21:02 1995
  71. +++ samba-1.9.14p3/source/change-log    Tue Nov  7 22:59:06 1995
  72. @@ -1617,9 +1617,18 @@
  73.      - made rename and unlink look at share locks on file
  74.      - clitar memory leak fix from jjm@jjm.com
  75.      - added -p option to smbstatus to list smbd processes
  76. +    - added rename to the client
  77.      - released p2
  78. +    - fixed SMBmv for case where the destination exists
  79. +    - man page patch from michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
  80. +    - once again redid the time handling, but finally explained what
  81. +    is going on, this is written up in TIME.txt. The "kludge-GMT" used
  82. +    by NT is a bastard and led to a lot of the confusion
  83. +    - kanji patch from fujita@ainix.isac.co.jp (Takashi Fujita)
  84. +    - is08859-1 patches from eauth@mail.cso.co.at
  85. +    - starting rewriting nmbd, new nmbd is nmbd2, old one still around
  86. +    for time being
  87.  
  88. -
  89.  ==========
  90.  todo:
  91.  
  92. @@ -1653,6 +1662,10 @@
  93.  document cnvchar stuff
  94.  
  95.  allow smbd to serve user and group lists to win95
  96. +
  97. +document homes behaviour with WinDD
  98. +
  99. +apparently WfWg doesn't like the password server stuff in 1.9.14. Why?
  100.  
  101.  UNRESOLVED PROBLEMS
  102.  ===================
  103. diff -u -r --new-file last-version/source/client.c samba-1.9.14p3/source/client.c
  104. --- last-version/source/client.c    Sat Nov  4 21:31:10 1995
  105. +++ samba-1.9.14p3/source/client.c    Tue Nov  7 13:59:55 1995
  106. @@ -444,12 +444,12 @@
  107.    ****************************************************************************/
  108.  static void display_finfo(file_info *finfo)
  109.  {
  110. -  time_t t = finfo->mtime - DSTDiff(finfo->mtime);
  111. +  time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
  112.    DEBUG(0,("  %-30s%7.7s%10d  %s",
  113.         CNV_LANG(finfo->name),
  114.         attrib_string(finfo->mode),
  115.         finfo->size,
  116. -       asctime(LocalTime(&t,0))));
  117. +       asctime(LocalTime(&t,GMT_TO_LOCAL))));
  118.  }
  119.  
  120.  /****************************************************************************
  121. @@ -492,7 +492,8 @@
  122.  {
  123.    finfo->mode = CVAL(p,21);
  124.  
  125. -  finfo->ctime = make_unix_date(p+22,True);
  126. +  /* this date is converted to GMT by make_unix_date */
  127. +  finfo->ctime = make_unix_date(p+22);
  128.    finfo->mtime = finfo->atime = finfo->ctime;
  129.    finfo->size = IVAL(p,26);
  130.    strcpy(finfo->name,p+30);
  131. @@ -516,9 +517,10 @@
  132.      case 1: /* OS/2 understands this */
  133.        if (finfo)
  134.      {
  135. -      finfo->ctime = make_unix_date2(p+4,True);
  136. -      finfo->atime = make_unix_date2(p+8,True);
  137. -      finfo->mtime = make_unix_date2(p+12,True);
  138. +      /* these dates are converted to GMT by make_unix_date */
  139. +      finfo->ctime = make_unix_date2(p+4);
  140. +      finfo->atime = make_unix_date2(p+8);
  141. +      finfo->mtime = make_unix_date2(p+12);
  142.        finfo->size = IVAL(p,16);
  143.        finfo->mode = CVAL(p,24);
  144.        strcpy(finfo->name,p+27);
  145. @@ -528,9 +530,10 @@
  146.      case 2: /* this is what OS/2 uses mostly */
  147.        if (finfo)
  148.      {
  149. -      finfo->ctime = make_unix_date2(p+4,True);
  150. -      finfo->atime = make_unix_date2(p+8,True);
  151. -      finfo->mtime = make_unix_date2(p+12,True);
  152. +      /* these dates are converted to GMT by make_unix_date */
  153. +      finfo->ctime = make_unix_date2(p+4);
  154. +      finfo->atime = make_unix_date2(p+8);
  155. +      finfo->mtime = make_unix_date2(p+12);
  156.        finfo->size = IVAL(p,16);
  157.        finfo->mode = CVAL(p,24);
  158.        strcpy(finfo->name,p+31);
  159. @@ -541,9 +544,10 @@
  160.      case 3:
  161.        if (finfo)
  162.      {
  163. -      finfo->ctime = make_unix_date2(p+8,True);
  164. -      finfo->atime = make_unix_date2(p+12,True);
  165. -      finfo->mtime = make_unix_date2(p+16,True);
  166. +      /* these dates are probably like the other ones */
  167. +      finfo->ctime = make_unix_date2(p+8);
  168. +      finfo->atime = make_unix_date2(p+12);
  169. +      finfo->mtime = make_unix_date2(p+16);
  170.        finfo->size = IVAL(p,20);
  171.        finfo->mode = CVAL(p,28);
  172.        strcpy(finfo->name,p+33);
  173. @@ -553,9 +557,10 @@
  174.      case 4:
  175.        if (finfo)
  176.      {
  177. -      finfo->ctime = make_unix_date2(p+8,True);
  178. -      finfo->atime = make_unix_date2(p+12,True);
  179. -      finfo->mtime = make_unix_date2(p+16,True);
  180. +      /* these dates are probably like the other ones */
  181. +      finfo->ctime = make_unix_date2(p+8);
  182. +      finfo->atime = make_unix_date2(p+12);
  183. +      finfo->mtime = make_unix_date2(p+16);
  184.        finfo->size = IVAL(p,20);
  185.        finfo->mode = CVAL(p,28);
  186.        strcpy(finfo->name,p+37);
  187. @@ -565,17 +570,24 @@
  188.      case 260: /* NT uses this, but also accepts 2 */
  189.        if (finfo)
  190.      {
  191. -      extern int serverzone;
  192.        int ret = SVAL(p,0);
  193.        int namelen;
  194.        p += 4; /* next entry offset */
  195.        p += 4; /* fileindex */
  196. +
  197. +      /* these dates appear to arrive in a weird way. It seems to
  198. +         be localtime plus the serverzone given in the initial
  199. +         connect. This is GMT when DST is not in effect and one
  200. +         hour from GMT otherwise. Can this really be right??
  201. +
  202. +         I suppose this could be called kludge-GMT. Is is the GMT
  203. +         you get by using the current DST setting on a different
  204. +         localtime. It will be cheap to calculate, I suppose, as
  205. +         no DST tables will be needed */
  206. +
  207.        finfo->ctime = interpret_long_date(p); p += 8;
  208.        finfo->atime = interpret_long_date(p); p += 8;
  209.        finfo->mtime = interpret_long_date(p); p += 8; p += 8;
  210. -      finfo->mtime += DSTDiff(finfo->mtime) - serverzone;
  211. -      finfo->ctime += DSTDiff(finfo->ctime) - serverzone;
  212. -      finfo->atime += DSTDiff(finfo->atime) - serverzone;
  213.        finfo->size = IVAL(p,0); p += 8;
  214.        p += 8; /* alloc size */
  215.        finfo->mode = CVAL(p,0); p += 4;
  216. @@ -1161,12 +1173,15 @@
  217.      }
  218.  
  219.    strcpy(finfo.name,rname);
  220. +
  221.    if (!finfo1)
  222.      {
  223.        finfo.mode = SVAL(inbuf,smb_vwv3);
  224. -      finfo.mtime = IVAL(inbuf,smb_vwv4);
  225. -      finfo.size = IVAL(inbuf,smb_vwv6);
  226. +      /* these times arrive as LOCAL time, using the DST offset 
  227. +     corresponding to that time, we convert them to GMT */
  228. +      finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
  229.        finfo.atime = finfo.ctime = finfo.mtime;
  230. +      finfo.size = IVAL(inbuf,smb_vwv6);
  231.      }
  232.  
  233.    DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
  234. @@ -1536,7 +1551,8 @@
  235.      if (lowercase)
  236.        strlower(finfo->name);
  237.  
  238. -    if (!directory_exist(finfo->name) && sys_mkdir(finfo->name,0777) != 0) 
  239. +    if (!directory_exist(finfo->name,NULL) && 
  240. +        sys_mkdir(finfo->name,0777) != 0) 
  241.        {
  242.          DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
  243.          strcpy(cur_dir,saved_curdir);
  244. @@ -1834,25 +1850,18 @@
  245.        return;
  246.      }
  247.  
  248. -  if (close_time != 0 && close_time != -1) 
  249. -    close_time -= TimeDiff(close_time);
  250. -  
  251.    bzero(outbuf,smb_size);
  252.    set_message(outbuf,3,2 + strlen(rname),True);
  253.  
  254.    if (finfo->mtime == 0 || finfo->mtime == -1)
  255. -    {
  256. -      time_t t = time(NULL);
  257. -      finfo->mtime = finfo->atime = finfo->ctime = 
  258. -    t + GMT_TO_LOCAL*TimeDiff(t);
  259. -    }
  260. -  
  261. +    finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
  262. +
  263.    CVAL(outbuf,smb_com) = SMBcreate;
  264.    SSVAL(outbuf,smb_tid,cnum);
  265.    setup_pkt(outbuf);
  266.  
  267.    SSVAL(outbuf,smb_vwv0,finfo->mode);
  268. -  SIVAL(outbuf,smb_vwv1,finfo->mtime);
  269. +  put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
  270.    
  271.    p = smb_buf(outbuf);
  272.    *p++ = 4;      
  273. @@ -1927,12 +1936,8 @@
  274.    SSVAL(outbuf,smb_tid,cnum);
  275.    setup_pkt(outbuf);
  276.  
  277. -  SSVAL(outbuf,smb_vwv0,fnum);
  278. -  SIVAL(outbuf,smb_vwv1,close_time);
  279. -
  280. -  DEBUG(3,("Setting date to %s (0x%X)",
  281. -       asctime(LocalTime(&finfo->mtime,LOCAL_TO_GMT)),
  282. -       finfo->mtime));
  283. +  SSVAL(outbuf,smb_vwv0,fnum);  
  284. +  put_dos_date3(outbuf,smb_vwv1,close_time);
  285.  
  286.    send_smb(outbuf);
  287.    receive_smb(inbuf,CLIENT_TIMEOUT);
  288. @@ -2000,8 +2005,14 @@
  289.  
  290.    dos_clean_name(rname);
  291.  
  292. -  /* let the remote side decide the date */
  293. -  finfo.mtime = -1;
  294. +  {
  295. +    struct stat st;
  296. +    if (!file_exist(lname,&st)) {
  297. +      DEBUG(0,("%s does not exist\n"));
  298. +      return;
  299. +    }
  300. +    finfo.mtime = st.st_mtime;
  301. +  }
  302.  
  303.    do_put(rname,lname,&finfo);
  304.  }
  305. @@ -2054,6 +2065,7 @@
  306.    
  307.    while (next_token(NULL,p,NULL))
  308.      {
  309. +      struct stat st;
  310.        pstring cmd;
  311.        pstring tmpname;
  312.        FILE *f;
  313. @@ -2078,7 +2090,7 @@
  314.      again1:
  315.  
  316.        /* check if it's a directory */
  317. -      if (directory_exist(lname))
  318. +      if (directory_exist(lname,&st))
  319.          {
  320.            if (!recurse) continue;
  321.            sprintf(quest,"Put directory %s? ",lname);
  322. @@ -2115,8 +2127,8 @@
  323.        /* null size so do_put knows to ignore it */
  324.        finfo.size = -1;
  325.  
  326. -      /* let the remote side decide the date */
  327. -      finfo.mtime = -1;
  328. +      /* set the date on the file */
  329. +      finfo.mtime = st.st_mtime;
  330.  
  331.        do_put(rname,lname,&finfo);
  332.      }
  333. @@ -2584,8 +2596,9 @@
  334.    ok = next_token(NULL,buf,NULL);
  335.    if (ok && (sys_stat(buf,&sbuf) == 0))
  336.      {
  337. -      newer_than = sbuf.st_mtime + GMT_TO_LOCAL*TimeDiff(sbuf.st_mtime);
  338. -      DEBUG(1,("Getting files newer than %s",asctime(LocalTime(&newer_than,0))));
  339. +      newer_than = sbuf.st_mtime;
  340. +      DEBUG(1,("Getting files newer than %s",
  341. +           asctime(LocalTime(&newer_than,GMT_TO_LOCAL))));
  342.      }
  343.    else
  344.      newer_than = 0;
  345. @@ -2895,8 +2908,9 @@
  346.      sec_mode = SVAL(inbuf,smb_vwv1);
  347.      max_xmit = SVAL(inbuf,smb_vwv2);
  348.      sesskey = IVAL(inbuf,smb_vwv6);
  349. -    servertime = make_unix_date(inbuf+smb_vwv8,False);
  350.      serverzone = SVALS(inbuf,smb_vwv10)*60;
  351. +    /* this time is converted to GMT by make_unix_date */
  352. +    servertime = make_unix_date(inbuf+smb_vwv8);
  353.      if (Protocol >= PROTOCOL_COREPLUS) {
  354.        readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
  355.        writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
  356. @@ -2913,8 +2927,8 @@
  357.      max_xmit = IVAL(inbuf,smb_vwv3+1);
  358.      sesskey = IVAL(inbuf,smb_vwv7+1);
  359.      serverzone = SVALS(inbuf,smb_vwv15+1)*60;
  360. +    /* this time arrives in real GMT */
  361.      servertime = interpret_long_date(inbuf+smb_vwv11+1);
  362. -    servertime -= serverzone;
  363.      crypt_len = CVAL(inbuf,smb_vwv16+1);
  364.      memcpy(cryptkey,smb_buf(inbuf),8);
  365.      if (IVAL(inbuf,smb_vwv9+1) & 1)
  366. @@ -2937,7 +2951,7 @@
  367.      static BOOL done_time = False;
  368.      if (!done_time) {
  369.        DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
  370. -           asctime(LocalTime(&servertime,0)),
  371. +           asctime(LocalTime(&servertime,GMT_TO_LOCAL)),
  372.             -(double)(serverzone/3600.0)));
  373.        done_time = True;
  374.      }
  375. @@ -3805,12 +3819,13 @@
  376.    pstring query_host;
  377.    BOOL message = False;
  378.  
  379. -  charset_initialise();
  380. -
  381.    *query_host = 0;
  382.  
  383.    DEBUGLEVEL = 2;
  384.    dbf = stdout;
  385. +
  386. +  TimeInit();
  387. +  charset_initialise();
  388.  
  389.    pid = getpid();
  390.    uid = getuid();
  391. diff -u -r --new-file last-version/source/clitar.c samba-1.9.14p3/source/clitar.c
  392. --- last-version/source/clitar.c    Sat Nov  4 23:05:01 1995
  393. +++ samba-1.9.14p3/source/clitar.c    Mon Nov  6 16:17:43 1995
  394. @@ -441,7 +441,7 @@
  395.      {
  396.        finfo.mode = SVAL(inbuf,smb_vwv3);
  397.        finfo.size = IVAL(inbuf,smb_vwv4);
  398. -      finfo.mtime = IVAL(inbuf,smb_vwv6);
  399. +      finfo.mtime = make_unix_date3(inbuf+smb_vwv6);
  400.        finfo.atime = finfo.ctime = finfo.mtime;
  401.      }
  402.  
  403. @@ -856,7 +856,6 @@
  404.     */
  405.    finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
  406.    finfo->atime = time(NULL);
  407. -  finfo->atime += GMT_TO_LOCAL*TimeDiff(finfo->atime);
  408.    finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
  409.  
  410.    return True;
  411. @@ -923,7 +922,7 @@
  412.    setup_pkt(outbuf);
  413.    
  414.    SSVAL(outbuf,smb_vwv0,finfo.mode);
  415. -  SIVAL(outbuf,smb_vwv1,finfo.mtime);
  416. +  put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
  417.    
  418.    p = smb_buf(outbuf);
  419.    *p++ = 4;      
  420. @@ -996,10 +995,10 @@
  421.    setup_pkt(outbuf);
  422.    
  423.    SSVAL(outbuf,smb_vwv0,fnum);
  424. -  SIVAL(outbuf,smb_vwv1,finfo.mtime-TimeDiff(finfo.mtime));
  425. +  put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
  426.    
  427.    DEBUG(3,("Setting date to %s (0x%X)",
  428. -       asctime(LocalTime(&finfo.mtime,LOCAL_TO_GMT)),
  429. +       asctime(LocalTime(&finfo.mtime,GMT_TO_LOCAL)),
  430.         finfo.mtime));
  431.    
  432.    send_smb(outbuf);
  433. diff -u -r --new-file last-version/source/dir.c samba-1.9.14p3/source/dir.c
  434. --- last-version/source/dir.c    Thu Sep 21 20:58:46 1995
  435. +++ samba-1.9.14p3/source/dir.c    Tue Nov  7 12:46:56 1995
  436. @@ -436,7 +436,7 @@
  437.        strcpy(filename,dname);      
  438.  
  439.        if ((strcmp(filename,mask) == 0) ||
  440. -      (name_convert(filename,dname,True,SNUM(cnum)) &&
  441. +      (name_map_mangle(filename,True,SNUM(cnum)) &&
  442.         mask_match(filename,mask,False,False)))
  443.      {
  444.        if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
  445. diff -u -r --new-file last-version/source/includes.h samba-1.9.14p3/source/includes.h
  446. --- last-version/source/includes.h    Sat Nov  4 21:51:34 1995
  447. +++ samba-1.9.14p3/source/includes.h    Tue Nov  7 12:49:21 1995
  448. @@ -84,7 +84,6 @@
  449.  #define PASSWORD_LENGTH 16
  450.  #endif
  451.  
  452. -
  453.  /* here is the general includes section - with some ifdefs generated 
  454.     by the previous section 
  455.  */
  456. @@ -755,6 +754,13 @@
  457.  end of the platform specific sections
  458.  ********************************************************************/
  459.  
  460. +#ifndef MAXINT
  461. +#define MAXINT ((((unsigned)1)<<(sizeof(int)*8-1))-1)
  462. +#endif
  463. +
  464. +#ifndef __STDC__
  465. +#define const
  466. +#endif
  467.  
  468.  /* Now for some other grungy stuff */
  469.  #ifdef NO_GETSPNAM
  470. @@ -958,6 +964,10 @@
  471.  #define F_WRLCK 0
  472.  #define F_UNLCK 0
  473.  #endif /* HAVE_FCNTL_LOCK == 0 */
  474. +
  475. +#ifdef NOSTRCASECMP
  476. +#define strcasecmp(s1,s2) StrCaseCmp(s1,s2)
  477. +#endif
  478.  
  479.  #ifndef strcpy
  480.  #define strcpy(dest,src) StrCpy(dest,src)
  481. diff -u -r --new-file last-version/source/ipc.c samba-1.9.14p3/source/ipc.c
  482. --- last-version/source/ipc.c    Sat Nov  4 18:58:24 1995
  483. +++ samba-1.9.14p3/source/ipc.c    Mon Nov  6 16:54:58 1995
  484. @@ -458,6 +458,11 @@
  485.                     struct pack_desc* desc,
  486.                     print_queue_struct* queue, int n)
  487.  {
  488. +  time_t t = queue->time;
  489. +
  490. +  /* the client expects localtime */
  491. +  t += GMT_TO_LOCAL*TimeDiff(t);
  492. +
  493.    PACKI(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */
  494.    if (uLevel == 1) {
  495.      PACKS(desc,"B21",queue->user); /* szUserName */
  496. @@ -709,8 +714,7 @@
  497.  /****************************************************************************
  498.    get info about a share
  499.    ****************************************************************************/
  500. -
  501. -static int check_share_info(int uLevel, const char* id)
  502. +static int check_share_info(int uLevel, char* id)
  503.  {
  504.    switch( uLevel ) {
  505.    case 0:
  506. @@ -944,11 +948,13 @@
  507.    {
  508.      struct tm *t;
  509.      time_t unixdate = time(NULL);
  510. -    unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
  511. +
  512. +    put_dos_date3(p,0,unixdate); /* this is the time that is looked at by NT 
  513. +                    in a "net time" operation */
  514.  
  515. -    t = LocalTime(&unixdate,0);
  516. +    /* the client expects to get localtime, not GMT */
  517. +    t = LocalTime(&unixdate,GMT_TO_LOCAL);
  518.  
  519. -    SIVAL(p,0,unixdate); 
  520.      SIVAL(p,4,0);        /* msecs ? */
  521.      CVAL(p,8) = t->tm_hour;
  522.      CVAL(p,9) = t->tm_min;
  523. @@ -995,7 +1001,7 @@
  524.  
  525.    DEBUG(3,("Set password for <%s>\n",user));
  526.  
  527. -  if (!password_ok(user,pass1,strlen(pass1),NULL) || 
  528. +  if (!password_ok(user,pass1,strlen(pass1),NULL,False) || 
  529.        !chgpasswd(user,pass1,pass2))
  530.      SSVAL(*rparam,0,NERR_badpass);
  531.  
  532. @@ -1128,7 +1134,7 @@
  533.    or   <WWsTP> <WB21BB16B10zWWzDDz> 
  534.  ****************************************************************************/
  535.  static int check_printjob_info(struct pack_desc* desc,
  536. -                   int uLevel, const char* id)
  537. +                   int uLevel, char* id)
  538.  {
  539.    desc->subformat = NULL;
  540.    switch( uLevel ) {
  541. @@ -1766,7 +1772,7 @@
  542.  }
  543.  
  544.  static int check_printdest_info(struct pack_desc* desc,
  545. -                int uLevel, const char* id)
  546. +                int uLevel, char* id)
  547.  {
  548.    desc->subformat = NULL;
  549.    switch( uLevel ) {
  550. diff -u -r --new-file last-version/source/kanji.h samba-1.9.14p3/source/kanji.h
  551. --- last-version/source/kanji.h    Thu Sep 21 20:49:48 1995
  552. +++ samba-1.9.14p3/source/kanji.h    Tue Nov  7 11:03:48 1995
  553. @@ -27,9 +27,6 @@
  554.  #define _KANJI_H_
  555.  
  556.  #ifdef KANJI
  557. -#ifndef REPLACE_RENAME
  558. -#define REPLACE_RENAME
  559. -#endif
  560.  
  561.  /* FOR SHIFT JIS CODE */
  562.  #define is_shift_jis(c) \
  563. diff -u -r --new-file last-version/source/local.h samba-1.9.14p3/source/local.h
  564. --- last-version/source/local.h    Sun Oct 22 13:51:03 1995
  565. +++ samba-1.9.14p3/source/local.h    Sun Nov  5 12:37:52 1995
  566. @@ -140,4 +140,9 @@
  567.  
  568.  #define SMB_ALIGNMENT 1
  569.  
  570. +
  571. +/* shall we support browse requests via a FIFO to nmbd? */
  572. +#define ENABLE_FIFO 1
  573. +
  574. +
  575.  #endif
  576. diff -u -r --new-file last-version/source/mangle.c samba-1.9.14p3/source/mangle.c
  577. --- last-version/source/mangle.c    Fri Sep 15 20:34:00 1995
  578. +++ samba-1.9.14p3/source/mangle.c    Tue Nov  7 12:33:19 1995
  579. @@ -533,11 +533,8 @@
  580.  /****************************************************************************
  581.  convert a filename to DOS format. return True if successful.
  582.  ****************************************************************************/
  583. -BOOL name_convert(char *OutName,char *InName,BOOL need83,int snum)
  584. +BOOL name_map_mangle(char *OutName,BOOL need83,int snum)
  585.  {
  586. -  /* initially just copy it */
  587. -  strcpy(OutName,unix2dos_format(InName,False));
  588. -
  589.    /* apply any name mappings */
  590.    {
  591.      char *map = lp_mangled_map(snum);
  592. diff -u -r --new-file last-version/source/md4.c samba-1.9.14p3/source/md4.c
  593. --- last-version/source/md4.c    Thu Jan  1 10:00:00 1970
  594. +++ samba-1.9.14p3/source/md4.c    Tue Nov  7 12:44:48 1995
  595. @@ -0,0 +1,299 @@
  596. +#ifdef SMB_PASSWD
  597. +/*
  598. +   This code is from rfc1186. 
  599. +*/
  600. +
  601. + /*
  602. + ** ********************************************************************
  603. + ** md4.c -- Implementation of MD4 Message Digest Algorithm           **
  604. + ** Updated: 2/16/90 by Ronald L. Rivest                              **
  605. + ** (C) 1990 RSA Data Security, Inc.                                  **
  606. + ** ********************************************************************
  607. + */
  608. +
  609. + /*
  610. + ** To use MD4:
  611. + **   -- Include md4.h in your program
  612. + **   -- Declare an MDstruct MD to hold the state of the digest
  613. + **          computation.
  614. + **   -- Initialize MD using MDbegin(&MD)
  615. + **   -- For each full block (64 bytes) X you wish to process, call
  616. + **          MDupdate(&MD,X,512)
  617. + **      (512 is the number of bits in a full block.)
  618. + **   -- For the last block (less than 64 bytes) you wish to process,
  619. + **          MDupdate(&MD,X,n)
  620. + **      where n is the number of bits in the partial block. A partial
  621. + **      block terminates the computation, so every MD computation
  622. + **      should terminate by processing a partial block, even if it
  623. + **      has n = 0.
  624. + **   -- The message digest is available in MD.buffer[0] ...
  625. + **      MD.buffer[3].  (Least-significant byte of each word
  626. + **      should be output first.)
  627. + **   -- You can print out the digest using MDprint(&MD)
  628. + */
  629. +
  630. + /* Implementation notes:
  631. + ** This implementation assumes that ints are 32-bit quantities.
  632. + ** If the machine stores the least-significant byte of an int in the
  633. + ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
  634. + ** should be set to TRUE.  Otherwise (e.g., SUNS), LOWBYTEFIRST
  635. + ** should be set to FALSE.  Note that on machines with LOWBYTEFIRST
  636. + ** FALSE the routine MDupdate modifies has a side-effect on its input
  637. + ** array (the order of bytes in each word are reversed).  If this is
  638. + ** undesired a call to MDreverse(X) can reverse the bytes of X back
  639. + ** into order after each call to MDupdate.
  640. + */
  641. +
  642. +#define TRUE  1
  643. +#define FALSE 0
  644. +
  645. + /* Compile-time includes
  646. + */
  647. +
  648. +#include <stdio.h>
  649. +#include "md4.h"
  650. +
  651. +#define uchar unsigned char
  652. +#define int16 unsigned short
  653. +#define uint32 unsigned int
  654. +#include "byteorder.h"
  655. +
  656. + /* Compile-time declarations of MD4 "magic constants".
  657. + */
  658. +#define I0  0x67452301       /* Initial values for MD buffer */
  659. +#define I1  0xefcdab89
  660. +#define I2  0x98badcfe
  661. +#define I3  0x10325476
  662. +#define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
  663. +#define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
  664. + /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
  665. + ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
  666. + ** Table 2, page 660.
  667. + */
  668. +
  669. +#define fs1  3               /* round 1 shift amounts */
  670. +#define fs2  7
  671. +#define fs3 11
  672. +#define fs4 19
  673. +#define gs1  3               /* round 2 shift amounts */
  674. +#define gs2  5
  675. +#define gs3  9
  676. +#define gs4 13
  677. +#define hs1  3               /* round 3 shift amounts */
  678. +#define hs2  9
  679. +#define hs3 11
  680. +#define hs4 15
  681. +
  682. + /* Compile-time macro declarations for MD4.
  683. + ** Note: The "rot" operator uses the variable "tmp".
  684. + ** It assumes tmp is declared as unsigned int, so that the >>
  685. + ** operator will shift in zeros rather than extending the sign bit.
  686. + */
  687. +#define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
  688. +#define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
  689. +#define h(X,Y,Z)             (X^Y^Z)
  690. +#define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
  691. +#define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
  692. +#define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
  693. +#define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
  694. +
  695. + /* MDprint(MDp)
  696. + ** Print message digest buffer MDp as 32 hexadecimal digits.
  697. + ** Order is from low-order byte of buffer[0] to high-order byte of
  698. + ** buffer[3].
  699. + ** Each byte is printed with high-order hexadecimal digit first.
  700. + ** This is a user-callable routine.
  701. + */
  702. + void
  703. + MDprint(MDp)
  704. + MDptr MDp;
  705. + { int i,j;
  706. +   for (i=0;i<4;i++)
  707. +     for (j=0;j<32;j=j+8)
  708. +       printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
  709. + }
  710. +
  711. + /* MDbegin(MDp)
  712. + ** Initialize message digest buffer MDp.
  713. + ** This is a user-callable routine.
  714. + */
  715. + void
  716. + MDbegin(MDp)
  717. + MDptr MDp;
  718. + { int i;
  719. +   MDp->buffer[0] = I0;
  720. +   MDp->buffer[1] = I1;
  721. +   MDp->buffer[2] = I2;
  722. +   MDp->buffer[3] = I3;
  723. +   for (i=0;i<8;i++) MDp->count[i] = 0;
  724. +   MDp->done = 0;
  725. + }
  726. +
  727. + /* MDreverse(X)
  728. + ** Reverse the byte-ordering of every int in X.
  729. + ** Assumes X is an array of 16 ints.
  730. + ** The macro revx reverses the byte-ordering of the next word of X.
  731. + */
  732. + void MDreverse(X)
  733. + unsigned int *X;
  734. + { register unsigned int t;
  735. +   register unsigned int i;
  736. +
  737. +   for(i = 0; i < 16; i++) {
  738. +      t = X[i];
  739. +      SIVAL(X,i*4,t);
  740. +    }
  741. + }
  742. +
  743. + /* MDblock(MDp,X)
  744. + ** Update message digest buffer MDp->buffer using 16-word data block X.
  745. + ** Assumes all 16 words of X are full of data.
  746. + ** Does not update MDp->count.
  747. + ** This routine is not user-callable.
  748. + */
  749. + static void
  750. + MDblock(MDp,X)
  751. + MDptr MDp;
  752. + unsigned int *X;
  753. + {
  754. +   register unsigned int tmp, A, B, C, D;
  755. +   MDreverse(X);
  756. +   A = MDp->buffer[0];
  757. +   B = MDp->buffer[1];
  758. +   C = MDp->buffer[2];
  759. +   D = MDp->buffer[3];
  760. +   /* Update the message digest buffer */
  761. +   ff(A , B , C , D ,  0 , fs1); /* Round 1 */
  762. +   ff(D , A , B , C ,  1 , fs2);
  763. +   ff(C , D , A , B ,  2 , fs3);
  764. +   ff(B , C , D , A ,  3 , fs4);
  765. +   ff(A , B , C , D ,  4 , fs1);
  766. +   ff(D , A , B , C ,  5 , fs2);
  767. +   ff(C , D , A , B ,  6 , fs3);
  768. +   ff(B , C , D , A ,  7 , fs4);
  769. +   ff(A , B , C , D ,  8 , fs1);
  770. +   ff(D , A , B , C ,  9 , fs2);
  771. +   ff(C , D , A , B , 10 , fs3);
  772. +   ff(B , C , D , A , 11 , fs4);
  773. +   ff(A , B , C , D , 12 , fs1);
  774. +   ff(D , A , B , C , 13 , fs2);
  775. +   ff(C , D , A , B , 14 , fs3);
  776. +   ff(B , C , D , A , 15 , fs4);
  777. +   gg(A , B , C , D ,  0 , gs1); /* Round 2 */
  778. +   gg(D , A , B , C ,  4 , gs2);
  779. +   gg(C , D , A , B ,  8 , gs3);
  780. +   gg(B , C , D , A , 12 , gs4);
  781. +   gg(A , B , C , D ,  1 , gs1);
  782. +   gg(D , A , B , C ,  5 , gs2);
  783. +   gg(C , D , A , B ,  9 , gs3);
  784. +   gg(B , C , D , A , 13 , gs4);
  785. +   gg(A , B , C , D ,  2 , gs1);
  786. +   gg(D , A , B , C ,  6 , gs2);
  787. +   gg(C , D , A , B , 10 , gs3);
  788. +   gg(B , C , D , A , 14 , gs4);
  789. +   gg(A , B , C , D ,  3 , gs1);
  790. +   gg(D , A , B , C ,  7 , gs2);
  791. +   gg(C , D , A , B , 11 , gs3);
  792. +   gg(B , C , D , A , 15 , gs4);
  793. +   hh(A , B , C , D ,  0 , hs1); /* Round 3 */
  794. +   hh(D , A , B , C ,  8 , hs2);
  795. +   hh(C , D , A , B ,  4 , hs3);
  796. +   hh(B , C , D , A , 12 , hs4);
  797. +   hh(A , B , C , D ,  2 , hs1);
  798. +   hh(D , A , B , C , 10 , hs2);
  799. +   hh(C , D , A , B ,  6 , hs3);
  800. +   hh(B , C , D , A , 14 , hs4);
  801. +   hh(A , B , C , D ,  1 , hs1);
  802. +   hh(D , A , B , C ,  9 , hs2);
  803. +   hh(C , D , A , B ,  5 , hs3);
  804. +   hh(B , C , D , A , 13 , hs4);
  805. +   hh(A , B , C , D ,  3 , hs1);
  806. +   hh(D , A , B , C , 11 , hs2);
  807. +   hh(C , D , A , B ,  7 , hs3);
  808. +   hh(B , C , D , A , 15 , hs4);
  809. +   MDp->buffer[0] += A;
  810. +   MDp->buffer[1] += B;
  811. +   MDp->buffer[2] += C;
  812. +   MDp->buffer[3] += D;
  813. + }
  814. +
  815. + /* MDupdate(MDp,X,count)
  816. + ** Input: MDp -- an MDptr
  817. + **        X -- a pointer to an array of unsigned characters.
  818. + **        count -- the number of bits of X to use.
  819. + **          (if not a multiple of 8, uses high bits of last byte.)
  820. + ** Update MDp using the number of bits of X given by count.
  821. + ** This is the basic input routine for an MD4 user.
  822. + ** The routine completes the MD computation when count < 512, so
  823. + ** every MD computation should end with one call to MDupdate with a
  824. + ** count less than 512.  A call with count 0 will be ignored if the
  825. + ** MD has already been terminated (done != 0), so an extra call with
  826. + ** count 0 can be given as a "courtesy close" to force termination
  827. + ** if desired.
  828. + */
  829. + void
  830. + MDupdate(MDp,X,count)
  831. + MDptr MDp;
  832. + unsigned char *X;
  833. + unsigned int count;
  834. + { unsigned int i, tmp, bit, byte, mask;
  835. +   unsigned char XX[64];
  836. +   unsigned char *p;
  837. +   /* return with no error if this is a courtesy close with count
  838. +   ** zero and MDp->done is true.
  839. +   */
  840. +   if (count == 0 && MDp->done) return;
  841. +   /* check to see if MD is already done and report error */
  842. +   if (MDp->done)
  843. +          { printf("\nError: MDupdate MD already done."); return; }
  844. +   /* Add count to MDp->count */
  845. +   tmp = count;
  846. +   p = MDp->count;
  847. +   while (tmp)
  848. +     { tmp += *p;
  849. +       *p++ = tmp;
  850. +       tmp = tmp >> 8;
  851. +     }
  852. +   /* Process data */
  853. +   if (count == 512)
  854. +     { /* Full block of data to handle */
  855. +       MDblock(MDp,(unsigned int *)X);
  856. +     }
  857. +   else if (count > 512) /* Check for count too large */
  858. +     { printf("\nError: MDupdate called with illegal count value %d."
  859. +              ,count);
  860. +       return;
  861. +     }
  862. +   else /* partial block -- must be last block so finish up */
  863. +     { /* Find out how many bytes and residual bits there are */
  864. +       byte = count >> 3;
  865. +       bit =  count & 7;
  866. +       /* Copy X into XX since we need to modify it */
  867. +       for (i=0;i<=byte;i++)   XX[i] = X[i];
  868. +       for (i=byte+1;i<64;i++) XX[i] = 0;
  869. +       /* Add padding '1' bit and low-order zeros in last byte */
  870. +       mask = 1 << (7 - bit);
  871. +       XX[byte] = (XX[byte] | mask) & ~( mask - 1);
  872. +       /* If room for bit count, finish up with this block */
  873. +       if (byte <= 55)
  874. +         { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
  875. +           MDblock(MDp,(unsigned int *)XX);
  876. +         }
  877. +       else /* need to do two blocks to finish up */
  878. +         { MDblock(MDp,(unsigned int *)XX);
  879. +           for (i=0;i<56;i++) XX[i] = 0;
  880. +           for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
  881. +           MDblock(MDp,(unsigned int *)XX);
  882. +         }
  883. +       /* Set flag saying we're done with MD computation */
  884. +       MDp->done = 1;
  885. +     }
  886. + }
  887. +
  888. + /*
  889. + ** End of md4.c
  890. + */
  891. +#else
  892. +void md4_dummy() {;}
  893. +#endif
  894. diff -u -r --new-file last-version/source/md4.h samba-1.9.14p3/source/md4.h
  895. --- last-version/source/md4.h    Thu Jan  1 10:00:00 1970
  896. +++ samba-1.9.14p3/source/md4.h    Tue Nov  7 10:50:21 1995
  897. @@ -0,0 +1,58 @@
  898. +/*
  899. +   This code is from rfc1186. 
  900. +*/
  901. +
  902. + /*
  903. + ** ********************************************************************
  904. + ** md4.h -- Header file for implementation of                        **
  905. + ** MD4 Message Digest Algorithm                                      **
  906. + ** Updated: 2/13/90 by Ronald L. Rivest                              **
  907. + ** (C) 1990 RSA Data Security, Inc.                                  **
  908. + ** ********************************************************************
  909. + */
  910. +
  911. + /* MDstruct is the data structure for a message digest computation.
  912. + */
  913. + typedef struct {
  914. +   unsigned int buffer[4]; /* Holds 4-word result of MD computation */
  915. +   unsigned char count[8]; /* Number of bits processed so far */
  916. +   unsigned int done;      /* Nonzero means MD computation finished */
  917. + } MDstruct, *MDptr;
  918. +
  919. + /* MDbegin(MD)
  920. +
  921. +
  922. +
  923. + ** Input: MD -- an MDptr
  924. + ** Initialize the MDstruct prepatory to doing a message digest
  925. + ** computation.
  926. + */
  927. + extern void MDbegin();
  928. +
  929. + /* MDupdate(MD,X,count)
  930. + ** Input: MD -- an MDptr
  931. + **        X -- a pointer to an array of unsigned characters.
  932. + **        count -- the number of bits of X to use (an unsigned int).
  933. + ** Updates MD using the first "count" bits of X.
  934. + ** The array pointed to by X is not modified.
  935. + ** If count is not a multiple of 8, MDupdate uses high bits of
  936. + ** last byte.
  937. + ** This is the basic input routine for a user.
  938. + ** The routine terminates the MD computation when count < 512, so
  939. + ** every MD computation should end with one call to MDupdate with a
  940. + ** count less than 512.  Zero is OK for a count.
  941. + */
  942. + extern void MDupdate();
  943. +
  944. + /* MDprint(MD)
  945. + ** Input: MD -- an MDptr
  946. + ** Prints message digest buffer MD as 32 hexadecimal digits.
  947. + ** Order is from low-order byte of buffer[0] to high-order byte
  948. + ** of buffer[3].
  949. + ** Each byte is printed with high-order hexadecimal digit first.
  950. + */
  951. + extern void MDprint();
  952. +
  953. + /*
  954. + ** End of md4.h
  955. + */
  956. diff -u -r --new-file last-version/source/mksmbpasswd.sh samba-1.9.14p3/source/mksmbpasswd.sh
  957. --- last-version/source/mksmbpasswd.sh    Tue Jul 11 13:41:45 1995
  958. +++ samba-1.9.14p3/source/mksmbpasswd.sh    Sun Nov  5 15:46:37 1995
  959. @@ -2,5 +2,5 @@
  960.  awk 'BEGIN {FS=":"
  961.      printf("#\n# SMB password file.\n#\n")
  962.      }
  963. -{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
  964. +{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
  965.  '
  966. diff -u -r --new-file last-version/source/nameserv.c samba-1.9.14p3/source/nameserv.c
  967. --- last-version/source/nameserv.c    Fri Sep 22 17:39:32 1995
  968. +++ samba-1.9.14p3/source/nameserv.c    Tue Nov  7 14:08:34 1995
  969. @@ -43,7 +43,6 @@
  970.  static int num_good_receives=0;
  971.  static pstring lookup="";
  972.  static int Client138=-1;
  973. -
  974.  enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
  975.  
  976.  /* this is the structure used for the local netbios name table */
  977. @@ -493,12 +492,13 @@
  978.  /****************************************************************************
  979.  interpret a node status response
  980.  ****************************************************************************/
  981. -static void interpret_node_status(char *inbuf,char *master)
  982. +static void interpret_node_status(char *inbuf, char *master)
  983.  {
  984.    int level = master?3:0;
  985.    char *p = inbuf + 12 + name_len(inbuf+12) + 10;
  986.    int numnames = CVAL(p,0);
  987.    DEBUG(level,("received %d names\n",numnames));
  988. +
  989.    p += 1;
  990.    while (numnames--)
  991.      {
  992. @@ -508,6 +508,7 @@
  993.        StrnCpy(qname,p,15);
  994.        type = CVAL(p,15);
  995.        p += 16;
  996. +
  997.        if (p[0] & 0x80) strcat(flags,"<GROUP> ");
  998.        if (p[0] & 0x60 == 0) strcat(flags,"B ");
  999.        if (p[0] & 0x60 == 1) strcat(flags,"P ");
  1000. @@ -649,8 +650,8 @@
  1001.  /****************************************************************************
  1002.  do a netbios name query to find someones IP
  1003.  ****************************************************************************/
  1004. -static BOOL name_query(char *name,char name_type,BOOL bcast,
  1005. -               struct in_addr to_ip,struct in_addr *ip,void (*fn)())
  1006. +static BOOL name_query(char *name, char name_type, BOOL bcast,
  1007. +               struct in_addr to_ip, struct in_addr *ip, void (*fn)())
  1008.  {
  1009.    BOOL found=False;
  1010.    pstring inbuf,outbuf;
  1011. @@ -738,7 +739,8 @@
  1012.  /****************************************************************************
  1013.  do a netbios name status to a host
  1014.  ****************************************************************************/
  1015. -static BOOL name_status(char *name,int type,struct in_addr to_ip,void (*fn)(),char *master)
  1016. +static BOOL name_status(char *name,int type,struct in_addr to_ip,void (*fn)(),
  1017. +                        char *master)
  1018.  {
  1019.    pstring inbuf,outbuf;
  1020.    static uint16 name_trn_id = 0x4262;
  1021. @@ -806,7 +808,7 @@
  1022.          if (rcode==0 && ancount==1 && qdcount==0) {
  1023.            DEBUG(fn?3:0,("Got a positive node status response from %s\n",
  1024.                  inet_ntoa(lastip)));
  1025. -          interpret_node_status(inbuf,master);
  1026. +          interpret_node_status(inbuf, master);
  1027.            return(True);
  1028.          }
  1029.          return(False);
  1030. @@ -1606,7 +1608,6 @@
  1031.    first = False;
  1032.  }
  1033.  
  1034. -
  1035.  /****************************************************************************
  1036.    process commands from the client
  1037.  ****************************************************************************/
  1038. @@ -1678,13 +1679,13 @@
  1039.  static BOOL open_sockets(BOOL isdaemon,int port)
  1040.  {
  1041.    struct hostent *hp;
  1042. -  
  1043.    /* get host info */
  1044.    if ((hp = Get_Hostbyname(myhostname)) == 0) 
  1045.      {
  1046.        DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  1047.        return False;
  1048. -    }
  1049. +    }   
  1050.  
  1051.    if (isdaemon)
  1052.      Client = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
  1053. @@ -1702,8 +1703,10 @@
  1054.    set_socket_options(Client138,"SO_BROADCAST");
  1055.    set_socket_options(Client,user_socket_options);
  1056.  
  1057. +
  1058. +  DEBUG(3, ("Socket opened.\n"));
  1059.    return True;
  1060. -}
  1061. +};
  1062.  
  1063.  
  1064.  /****************************************************************************
  1065. @@ -1734,7 +1737,8 @@
  1066.        Netmask = ip2;   
  1067.        } 
  1068.  
  1069. -    DEBUG(1,("Using IP %s  ",inet_ntoa(myip)));
  1070. +    DEBUG(1,("Using IP %s  ",inet_ntoa(myip))); /* core dump reported 
  1071. +                           doing this. Why?? XXXXX  */
  1072.      DEBUG(1,("broadcast %s  ",inet_ntoa(bcast_ip)));
  1073.      DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));    
  1074.  
  1075. @@ -1797,6 +1801,8 @@
  1076.  
  1077.    *lookup = *host_file = 0;
  1078.  
  1079. +  TimeInit();
  1080. +
  1081.    charset_initialise();
  1082.  
  1083.    strcpy(debugf,NMBLOGFILE);
  1084. @@ -1988,6 +1994,9 @@
  1085.      DEBUG(2,("%s becoming a daemon\n",timestring()));
  1086.      become_daemon();
  1087.    }
  1088. +
  1089. +
  1090. +  DEBUG(3,("Opening sockets\n"));
  1091.  
  1092.    if (open_sockets(is_daemon,port))
  1093.      {
  1094. diff -u -r --new-file last-version/source/nameserv.h samba-1.9.14p3/source/nameserv.h
  1095. --- last-version/source/nameserv.h    Thu Jan  1 10:00:00 1970
  1096. +++ samba-1.9.14p3/source/nameserv.h    Tue Nov  7 22:17:38 1995
  1097. @@ -0,0 +1,130 @@
  1098. +/* 
  1099. +   Unix SMB/Netbios implementation.
  1100. +   Version 1.9.
  1101. +   NBT netbios header - version 2
  1102. +   Copyright (C) Andrew Tridgell 1994-1995
  1103. +   
  1104. +   This program is free software; you can redistribute it and/or modify
  1105. +   it under the terms of the GNU General Public License as published by
  1106. +   the Free Software Foundation; either version 2 of the License, or
  1107. +   (at your option) any later version.
  1108. +   
  1109. +   This program is distributed in the hope that it will be useful,
  1110. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1111. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1112. +   GNU General Public License for more details.
  1113. +   
  1114. +   You should have received a copy of the GNU General Public License
  1115. +   along with this program; if not, write to the Free Software
  1116. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1117. +   
  1118. +*/
  1119. +
  1120. +#define MAX_DGRAM_SIZE 576
  1121. +#define MIN_DGRAM_SIZE 12
  1122. +
  1123. +#define NMB_PORT 137
  1124. +#define DGRAM_PORT 138
  1125. +
  1126. +/* a netbios name structure */
  1127. +struct nmb_name {
  1128. +  char name[17];
  1129. +  char scope[64];
  1130. +  int name_type;
  1131. +};
  1132. +
  1133. +/* a resource record */
  1134. +struct res_rec {
  1135. +  struct nmb_name rr_name;
  1136. +  int rr_type;
  1137. +  int rr_class;
  1138. +  int ttl;
  1139. +  int rdlength;
  1140. +  char rdata[MAX_DGRAM_SIZE];
  1141. +};
  1142. +
  1143. +/* define a nmb packet. */
  1144. +struct nmb_packet
  1145. +{
  1146. +  struct {
  1147. +    int name_trn_id;
  1148. +    int opcode;
  1149. +    BOOL response;
  1150. +    struct {
  1151. +      BOOL bcast;
  1152. +      BOOL recursion_available;
  1153. +      BOOL recursion_desired;
  1154. +      BOOL trunc;
  1155. +      BOOL authoritative;
  1156. +    } nm_flags;
  1157. +    int rcode;
  1158. +    int qdcount;
  1159. +    int ancount;
  1160. +    int nscount;
  1161. +    int arcount;
  1162. +  } header;
  1163. +
  1164. +  struct {
  1165. +    struct nmb_name question_name;
  1166. +    int question_type;
  1167. +    int question_class;
  1168. +  } question;
  1169. +
  1170. +  struct res_rec *answers;
  1171. +  struct res_rec *nsrecs;
  1172. +  struct res_rec *additional;
  1173. +};
  1174. +
  1175. +
  1176. +/* a datagram - a simple structure at first, it would be good to parse
  1177. +   it properly later */
  1178. +struct dgram_packet {
  1179. +  struct {
  1180. +    int res;
  1181. +    int id;
  1182. +    struct in_addr ip;
  1183. +    int port;
  1184. +    int length;
  1185. +    int res2;
  1186. +    struct nmb_name source_name;
  1187. +    struct nmb_name dest_name;
  1188. +  } header;
  1189. +  int smbsize;
  1190. +  char smb_data[MAX_DGRAM_SIZE];
  1191. +};
  1192. +
  1193. +enum packet_type {NMB_PACKET, DGRAM_PACKET};
  1194. +
  1195. +/* define a structure used to queue packets. this will be a linked
  1196. + list of nmb packets */
  1197. +struct packet_struct
  1198. +{
  1199. +  struct packet_struct *next;
  1200. +  struct packet_struct *prev;
  1201. +  struct in_addr ip;
  1202. +  int port;
  1203. +  int fd;
  1204. +  time_t timestamp;
  1205. +  enum packet_type packet_type;
  1206. +  union {
  1207. +    struct nmb_packet nmb;
  1208. +    struct dgram_packet dgram;
  1209. +  } packet;
  1210. +};
  1211. +
  1212. +
  1213. +/* this defines a list of network interfaces */
  1214. +struct net_interface {
  1215. +  struct net_interface *next;
  1216. +  struct in_addr ip;
  1217. +  struct in_addr bcast;
  1218. +  struct in_addr netmask;
  1219. +};
  1220. +
  1221. +
  1222. +/* prototypes */
  1223. +void free_nmb_packet(struct nmb_packet *nmb);
  1224. +void free_packet(struct packet_struct *packet);
  1225. +struct packet_struct *read_packet(int fd,enum packet_type packet_type);
  1226. +BOOL send_packet(struct packet_struct *p);
  1227. +struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
  1228. diff -u -r --new-file last-version/source/nameserv2.c samba-1.9.14p3/source/nameserv2.c
  1229. --- last-version/source/nameserv2.c    Thu Jan  1 10:00:00 1970
  1230. +++ samba-1.9.14p3/source/nameserv2.c    Tue Nov  7 22:37:02 1995
  1231. @@ -0,0 +1,1980 @@
  1232. +/* 
  1233. +   Unix SMB/Netbios implementation.
  1234. +   Version 1.9.
  1235. +   NBT netbios routines and daemon - version 2
  1236. +   Copyright (C) Andrew Tridgell 1994-1995
  1237. +   
  1238. +   This program is free software; you can redistribute it and/or modify
  1239. +   it under the terms of the GNU General Public License as published by
  1240. +   the Free Software Foundation; either version 2 of the License, or
  1241. +   (at your option) any later version.
  1242. +   
  1243. +   This program is distributed in the hope that it will be useful,
  1244. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1245. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1246. +   GNU General Public License for more details.
  1247. +   
  1248. +   You should have received a copy of the GNU General Public License
  1249. +   along with this program; if not, write to the Free Software
  1250. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1251. +   
  1252. +*/
  1253. +
  1254. +#include "includes.h"
  1255. +#include "nameserv.h"
  1256. +
  1257. +
  1258. +static void queue_packet(struct packet_struct *packet);
  1259. +
  1260. +
  1261. +extern int DEBUGLEVEL;
  1262. +
  1263. +/* the list of network interfaces */
  1264. +struct net_interface *interfaces = NULL;
  1265. +
  1266. +extern pstring debugf;
  1267. +extern int DEBUGLEVEL;
  1268. +
  1269. +extern pstring scope;
  1270. +
  1271. +static int browse_interval = BROWSE_INTERVAL;
  1272. +
  1273. +static BOOL dns_serve = False;
  1274. +static BOOL CanRecurse = True;
  1275. +
  1276. +extern struct in_addr lastip;
  1277. +extern int lastport;
  1278. +extern struct in_addr myip;
  1279. +extern struct in_addr bcast_ip;
  1280. +extern struct in_addr Netmask;
  1281. +extern pstring myhostname;
  1282. +static pstring host_file;
  1283. +static pstring myname="";
  1284. +static pstring lookup="";
  1285. +static int ClientNMB=-1;
  1286. +static int ClientDGRAM=-1;
  1287. +enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
  1288. +
  1289. +/* this is the structure used for the local netbios name table */
  1290. +typedef struct
  1291. +{
  1292. +  time_t start_time;
  1293. +  int ttl;
  1294. +  struct in_addr ip;
  1295. +  struct in_addr master_ip;
  1296. +  BOOL found_master;
  1297. +  BOOL valid;
  1298. +  BOOL isgroup;
  1299. +  BOOL unicast;
  1300. +  char name[100];
  1301. +  int type;
  1302. +  int count;  
  1303. +  enum name_sources source;
  1304. +} name_struct;
  1305. +
  1306. +
  1307. +static int num_names=0;
  1308. +static name_struct *names = NULL;
  1309. +
  1310. +#define NAMEVALID(i) names[i].valid
  1311. +#define ISGROUP(i) (names[i].isgroup)
  1312. +
  1313. +void process(void);
  1314. +
  1315. +/* are we running as a daemon ? */
  1316. +static BOOL is_daemon = False;
  1317. +
  1318. +/* machine comment */
  1319. +static pstring comment="";
  1320. +
  1321. +extern pstring user_socket_options;
  1322. +
  1323. +static void add_group_name(char *name);
  1324. +static void add_host_name(char *name,int type,struct in_addr *ip);
  1325. +static void dump_names(void);
  1326. +
  1327. +
  1328. +static BOOL got_bcast = False;
  1329. +static BOOL got_myip = False;
  1330. +static BOOL got_nmask = False;
  1331. +
  1332. +
  1333. +/****************************************************************************
  1334. +catch a sighup
  1335. +****************************************************************************/
  1336. +static int sig_hup()
  1337. +{
  1338. +  BlockSignals(True);
  1339. +
  1340. +  DEBUG(0,("Got SIGHUP - not implemented\n"));
  1341. +  dump_names();
  1342. +  if (!is_daemon)
  1343. +    exit(1);
  1344. +
  1345. +  BlockSignals(False);
  1346. +#ifndef DONT_REINSTALL_SIG
  1347. +  signal(SIGHUP,SIGNAL_CAST sig_hup);
  1348. +#endif
  1349. +  return(0);
  1350. +}
  1351. +
  1352. +/****************************************************************************
  1353. +catch a sigpipe
  1354. +****************************************************************************/
  1355. +static int sig_pipe()
  1356. +{
  1357. +  BlockSignals(True);
  1358. +
  1359. +  DEBUG(0,("Got SIGPIPE\n"));
  1360. +  if (!is_daemon)
  1361. +    exit(1);
  1362. +  BlockSignals(False);
  1363. +  return(0);
  1364. +}
  1365. +
  1366. +/****************************************************************************
  1367. +possibly continue after a fault
  1368. +****************************************************************************/
  1369. +static void fault_continue(void)
  1370. +{
  1371. +  static int errcount=0;
  1372. +
  1373. +  errcount++;
  1374. +
  1375. +  if (is_daemon && errcount<100)
  1376. +    process();
  1377. +
  1378. +  exit(1);
  1379. +}
  1380. +
  1381. +/****************************************************************************
  1382. +  true if two netbios names are equal
  1383. +****************************************************************************/
  1384. +static BOOL name_equal(char *s1,char *s2,int type1,int type2)
  1385. +{
  1386. +  char n1[20],n2[20];
  1387. +
  1388. +  if (type1 != type2) return(False);
  1389. +
  1390. +  StrnCpy(n1,s1,15);
  1391. +  StrnCpy(n2,s2,15);
  1392. +
  1393. +  trim_string(n1,NULL," ");
  1394. +  trim_string(n2,NULL," ");
  1395. +
  1396. +  return(strequal(n1,n2));
  1397. +}
  1398. +
  1399. +/****************************************************************************
  1400. +add a netbios name
  1401. +****************************************************************************/
  1402. +static int add_name(void)
  1403. +{
  1404. +  int i;
  1405. +
  1406. +  for (i=0;i<num_names;i++)
  1407. +    if (!names[i].valid)
  1408. +      break;
  1409. +
  1410. +  if (i==num_names) {
  1411. +    name_struct *n;
  1412. +    if (num_names == 0)    
  1413. +      n = (name_struct *)malloc(sizeof(name_struct));
  1414. +    else
  1415. +      n = (name_struct *)realloc(names,sizeof(name_struct)*(num_names+1));
  1416. +    if (!n) {
  1417. +      DEBUG(0,("Can't malloc more names space!\n"));
  1418. +      return(-1);
  1419. +    }
  1420. +    i = num_names;
  1421. +    num_names++;
  1422. +    names = n;
  1423. +  }
  1424. +
  1425. +  bzero(&names[i],sizeof(names[i]));
  1426. +
  1427. +  return(i);
  1428. +}
  1429. +
  1430. +/****************************************************************************
  1431. +find a name
  1432. +****************************************************************************/
  1433. +static int find_name(char *s,int type,BOOL groups)
  1434. +{
  1435. +  int i;
  1436. +  time_t t = time(NULL);
  1437. +
  1438. +  for (i=0;i<num_names;i++)
  1439. +    if (names[i].valid && (groups || !ISGROUP(i)))
  1440. +      {
  1441. +    if ((names[i].ttl > 0) && (t > (names[i].start_time + names[i].ttl)))
  1442. +      names[i].valid = False;
  1443. +    else
  1444. +      {
  1445. +        if (name_equal(s,names[i].name,type,names[i].type)) {
  1446. +          return(i);
  1447. +        }
  1448. +      }
  1449. +      }
  1450. +  return -1;
  1451. +}
  1452. +
  1453. +
  1454. +/****************************************************************************
  1455. +check names, and change any 0 IPs to myip
  1456. +****************************************************************************/
  1457. +static void check_names(void)
  1458. +{
  1459. +  int i;
  1460. +  int group_count=0;
  1461. +
  1462. +  /* add the magic __SAMBA__ name */
  1463. +  add_host_name("__SAMBA__",0x20,&myip);
  1464. +  add_host_name("__SAMBA__",0x0,&myip);
  1465. +
  1466. +  for (i=0;i<num_names;i++)
  1467. +    if (names[i].valid) {
  1468. +      if (ISGROUP(i)) group_count++;
  1469. +    }
  1470. +
  1471. +  if (group_count == 0)
  1472. +    add_group_name(WORKGROUP);
  1473. +
  1474. +
  1475. +  for (i=0;i<num_names;i++)
  1476. +    if (names[i].valid && strequal((char *)inet_ntoa(names[i].ip),"0.0.0.0"))
  1477. +      names[i].ip = (ISGROUP(i)?bcast_ip:myip);
  1478. +}
  1479. +
  1480. +
  1481. +/****************************************************************************
  1482. +dump a copy of the name table
  1483. +****************************************************************************/
  1484. +static void dump_names(void)
  1485. +{
  1486. +  int i;
  1487. +  DEBUG(3,("Dump of local name table\n"));
  1488. +  for (i=0;i<num_names;i++)
  1489. +    if (names[i].valid) {
  1490. +      DEBUG(3,("%s %s %d %s",
  1491. +           names[i].name,inet_ntoa(names[i].ip),
  1492. +           names[i].ttl,BOOLSTR(names[i].isgroup)));
  1493. +      if (names[i].found_master) 
  1494. +    DEBUG(3,(" %s",inet_ntoa(names[i].master_ip)));
  1495. +      DEBUG(3,("\n"));
  1496. +    }
  1497. +}
  1498. +
  1499. +
  1500. +/****************************************************************************
  1501. +load a netbios hosts file
  1502. +****************************************************************************/
  1503. +static void load_hosts_file(char *fname)
  1504. +{
  1505. +  int i;
  1506. +  FILE *f = fopen(fname,"r");
  1507. +  pstring line;
  1508. +  if (!f) 
  1509. +    {
  1510. +      DEBUG(2,("Not using non-existant lmhosts file %s\n",fname));
  1511. +      return;
  1512. +    }
  1513. +
  1514. +  while (!feof(f))
  1515. +    {
  1516. +      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  1517. +      
  1518. +      if (*line == '#') continue;
  1519. +
  1520. +      {
  1521. +    string ip="",name="",flags="",extra="";
  1522. +    unsigned long a;
  1523. +    char *ptr;
  1524. +    int count = 0;
  1525. +    ptr = line;
  1526. +    if (next_token(&ptr,ip,NULL)) ++count;
  1527. +    if (next_token(&ptr,name,NULL)) ++count;
  1528. +    if (next_token(&ptr,flags,NULL)) ++count;
  1529. +    if (next_token(&ptr,extra,NULL)) ++count;
  1530. +
  1531. +    if (count <= 0) continue;
  1532. +
  1533. +    if (count > 0 && count < 2)
  1534. +      {
  1535. +        DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  1536. +        continue;
  1537. +      }
  1538. +
  1539. +    i = add_name();
  1540. +    if (i < 0) 
  1541. +      {
  1542. +        fclose(f);
  1543. +        return;
  1544. +      }
  1545. +
  1546. +    a = interpret_addr(ip);
  1547. +    putip((char *)&names[i].ip,(char *)&a);
  1548. +
  1549. +    names[i].valid = True;
  1550. +    names[i].source = LMHOSTS;
  1551. +
  1552. +    StrnCpy(names[i].name,name,15);
  1553. +    if (strchr(flags,'G') || strchr(flags,'S'))
  1554. +      names[i].isgroup = True;
  1555. +    if (strchr(flags,'M') && !ISGROUP(i))
  1556. +      strcpy(myname,name);
  1557. +    if (strchr(flags,'U'))
  1558. +      names[i].unicast = True;
  1559. +    if (names[i].isgroup) 
  1560. +      names[i].type = 0xF0; /* hopefully invalid */
  1561. +    else
  1562. +      names[i].type = 0x20;
  1563. +      }      
  1564. +    }
  1565. +
  1566. +  fclose(f);
  1567. +}
  1568. +
  1569. +
  1570. +/****************************************************************************
  1571. +add a netbios group name
  1572. +****************************************************************************/
  1573. +static void add_group_name(char *name)
  1574. +{
  1575. +  int i = add_name();
  1576. +  if (i < 0) 
  1577. +    return;
  1578. +
  1579. +  bzero((char *)&names[i].ip,sizeof(names[i].ip));
  1580. +
  1581. +  strcpy(names[i].name,name);
  1582. +  names[i].isgroup = True;
  1583. +  names[i].valid = True;
  1584. +  names[i].type = 0xF0;
  1585. +  names[i].source = SELF;
  1586. +}
  1587. +
  1588. +/****************************************************************************
  1589. +add a host name
  1590. +****************************************************************************/
  1591. +static void add_host_name(char *name,int type,struct in_addr *ip)
  1592. +{
  1593. +  int i;
  1594. +
  1595. +  if (find_name(name,type,True) >= 0) return;
  1596. +
  1597. +  i = add_name();
  1598. +  if (i < 0) 
  1599. +    return;
  1600. +
  1601. +  names[i].ip = *ip;
  1602. +  strcpy(names[i].name,name);
  1603. +  names[i].valid = True;
  1604. +  names[i].start_time = time(NULL);
  1605. +  names[i].ttl = 0;
  1606. +  names[i].type = type;
  1607. +  names[i].source = SELF;
  1608. +}
  1609. +
  1610. +/****************************************************************************
  1611. +work out the length of a nmb message
  1612. +****************************************************************************/
  1613. +static int nmb_len(char *buf)
  1614. +{
  1615. +int i;
  1616. +int ret = 12;
  1617. +char *p = buf;
  1618. +int qdcount = RSVAL(buf,4);
  1619. +int ancount = RSVAL(buf,6);
  1620. +int nscount = RSVAL(buf,8);
  1621. +int arcount = RSVAL(buf,10);
  1622. +
  1623. +/* check for insane qdcount values? */
  1624. +if (qdcount > 100 || qdcount < 0)
  1625. +  {
  1626. +    DEBUG(6,("Invalid qdcount? qdcount=%d\n",qdcount));
  1627. +    return(0);
  1628. +  }
  1629. +
  1630. +for (i=0;i<qdcount;i++)
  1631. +  {
  1632. +    p = buf + ret;
  1633. +    ret += name_len(p) + 4;
  1634. +  }
  1635. +
  1636. +for (i=0;i<(ancount + nscount + arcount);i++)
  1637. +  {
  1638. +    int rdlength;
  1639. +    p = buf + ret;
  1640. +    ret += name_len(p) + 8;
  1641. +    p = buf + ret;
  1642. +    rdlength = RSVAL(p,0);
  1643. +    ret += rdlength + 2;
  1644. +  }
  1645. +
  1646. +return(ret);
  1647. +}
  1648. +
  1649. +/****************************************************************************
  1650. +receive a name message. timeout is in milliseconds
  1651. +****************************************************************************/
  1652. +static int receive_nmb(char *buffer,int timeout)
  1653. +{
  1654. +  int ret = read_max_udp(ClientNMB,buffer,sizeof(pstring),timeout);
  1655. +
  1656. +  if (ret < 0)
  1657. +    {
  1658. +      DEBUG(0,("No bytes from client\n"));
  1659. +      if (!is_daemon)
  1660. +    {
  1661. +      close_sockets();
  1662. +      exit(0);
  1663. +    }
  1664. +    }
  1665. +  
  1666. +  if (ret <= 1)
  1667. +    return 0;
  1668. +
  1669. +  log_in(buffer,ret);
  1670. +
  1671. +  DEBUG(3,("received packet from (%s) nmb_len=%d len=%d\n",
  1672. +    inet_ntoa(lastip),nmb_len(buffer),ret));
  1673. +
  1674. +  return(ret);
  1675. +}
  1676. +
  1677. +/****************************************************************************
  1678. +send a name message
  1679. +****************************************************************************/
  1680. +static BOOL send_nmb(char *buf, int len, struct in_addr *ip,int port)
  1681. +{
  1682. +  BOOL ret;
  1683. +  struct sockaddr_in sock_out;
  1684. +
  1685. +  /* set the address and port */
  1686. +  bzero((char *)&sock_out,sizeof(sock_out));
  1687. +  putip((char *)&sock_out.sin_addr,(char *)ip);
  1688. +  sock_out.sin_port = htons( port );
  1689. +  sock_out.sin_family = AF_INET;
  1690. +  
  1691. +  /* log the packet */
  1692. +  log_out(buf,len);
  1693. +
  1694. +  if (DEBUGLEVEL > 0)
  1695. +    DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
  1696. +      len,inet_ntoa(*ip)));
  1697. +    
  1698. +  /* send it */
  1699. +  ret = (sendto(ClientNMB,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
  1700. +
  1701. +  if (!ret)
  1702. +    DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
  1703. +
  1704. +  return(ret);
  1705. +}
  1706. +
  1707. +/*******************************************************************
  1708. +check if an IP is on my net
  1709. +********************************************************************/
  1710. +static BOOL is_mynet(struct in_addr ip)
  1711. +{
  1712. +  unsigned int net1,net2,nmask,subnet1,subnet2;
  1713. +
  1714. +  nmask   = *(unsigned int *)&Netmask;
  1715. +  net1    = (*(unsigned int *)&myip);
  1716. +  subnet1 = net1 & nmask;
  1717. +  net2    = (*(unsigned int *)&ip);
  1718. +  subnet2 = net2 & nmask;
  1719. +        
  1720. +  return((net1 != net2) && (subnet1 == subnet2));
  1721. +}
  1722. +
  1723. +/****************************************************************************
  1724. +interpret a node status response
  1725. +****************************************************************************/
  1726. +static void interpret_node_status(char *inbuf, char *master)
  1727. +{
  1728. +  int level = master?3:0;
  1729. +  char *p = inbuf + 12 + name_len(inbuf+12) + 10;
  1730. +  int numnames = CVAL(p,0);
  1731. +  DEBUG(level,("received %d names\n",numnames));
  1732. +
  1733. +  p += 1;
  1734. +  while (numnames--)
  1735. +    {
  1736. +      char qname[17];
  1737. +      int type;
  1738. +      fstring flags="";
  1739. +      StrnCpy(qname,p,15);
  1740. +      type = CVAL(p,15);
  1741. +      p += 16;
  1742. +
  1743. +      if (p[0] & 0x80) strcat(flags,"<GROUP> ");
  1744. +      if (p[0] & 0x60 == 0) strcat(flags,"B ");
  1745. +      if (p[0] & 0x60 == 1) strcat(flags,"P ");
  1746. +      if (p[0] & 0x60 == 2) strcat(flags,"M ");
  1747. +      if (p[0] & 0x60 == 3) strcat(flags,"_ ");
  1748. +      if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  1749. +      if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  1750. +      if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  1751. +      if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  1752. +
  1753. +      if (master && type == 0x1d) {
  1754. +    StrnCpy(master,qname,15);
  1755. +      }
  1756. +      
  1757. +      DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
  1758. +      p+=2;
  1759. +    }
  1760. +  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  1761. +           IVAL(p,20),IVAL(p,24)));
  1762. +}
  1763. +
  1764. +
  1765. +/****************************************************************************
  1766. +show a nmb message
  1767. +****************************************************************************/
  1768. +static void show_nmb(char *inbuf)
  1769. +{
  1770. +  int i,l;
  1771. +  int name_trn_id = RSVAL(inbuf,0);
  1772. +  int opcode = (CVAL(inbuf,2) >> 3) & 0xF;
  1773. +  int nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
  1774. +  int rcode = CVAL(inbuf,3) & 0xF;
  1775. +  int qdcount = RSVAL(inbuf,4);
  1776. +  int ancount = RSVAL(inbuf,6);
  1777. +  int nscount = RSVAL(inbuf,8);
  1778. +  int arcount = RSVAL(inbuf,10);
  1779. +  char name[100];
  1780. +
  1781. +  if (DEBUGLEVEL < 3) return;
  1782. +
  1783. +  DEBUG(3,("\nPACKET INTERPRETATION\n"));
  1784. +
  1785. +  if (opcode == 5 && ((nm_flags & ~1) == 0x10) && rcode == 0)
  1786. +    DEBUG(3,("NAME REGISTRATION REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1787. +
  1788. +  if (opcode == 5 && ((nm_flags & ~1) == 0x00) && rcode == 0)
  1789. +    DEBUG(3,("NAME OVERWRITE REQUEST AND DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1790. +  
  1791. +  if (opcode == 9 && ((nm_flags & ~1) == 0x00) && rcode == 0)
  1792. +    DEBUG(3,("NAME REFRESH REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1793. +
  1794. +  if (opcode == 8)
  1795. +    DEBUG(3,("NAME REFRESH (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1796. +  
  1797. +  if (opcode == 5 && nm_flags == 0x58 && rcode == 0)
  1798. +    DEBUG(3,("POSITIVE NAME REGISTRATION RESPONSE\n"));
  1799. +  
  1800. +  if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode != 7)
  1801. +    DEBUG(3,("NEGATIVE NAME REGISTRATION RESPONSE\n"));
  1802. +  
  1803. +  if (opcode == 5 && nm_flags == 0x50 && rcode == 0)
  1804. +    DEBUG(3,("END-NODE CHALLENGE REGISTRATION RESPONSE\n"));
  1805. +  
  1806. +  if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode == 7)
  1807. +    DEBUG(3,("NAME CONFLICT DEMAND\n"));
  1808. +  
  1809. +  if (opcode == 6 && (nm_flags&~1) == 0x00 && rcode == 0)
  1810. +    DEBUG(3,("NAME RELEASE REQUEST & DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1811. +  
  1812. +  if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode == 0)
  1813. +    DEBUG(3,("POSITIVE NAME RELEASE RESPONSE\n"));
  1814. +  
  1815. +  if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode != 0)
  1816. +    DEBUG(3,("NEGATIVE NAME RELEASE RESPONSE\n"));
  1817. +  
  1818. +  if (opcode == 0 && (nm_flags&~1) == 0x10 && rcode == 0)
  1819. +    DEBUG(3,("NAME QUERY REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1820. +  
  1821. +  if (opcode == 0 && (nm_flags&~0x28) == 0x50 && rcode == 0)
  1822. +    DEBUG(3,("POSITIVE NAME QUERY RESPONSE\n"));
  1823. +  
  1824. +  if (opcode == 0 && (nm_flags&~0x08) == 0x50 && rcode != 0)
  1825. +    DEBUG(3,("NEGATIVE NAME QUERY RESPONSE\n"));
  1826. +  
  1827. +  if (opcode == 0 && nm_flags == 0x10 && rcode == 0)
  1828. +    DEBUG(3,("REDIRECT NAME QUERY RESPONSE\n"));
  1829. +
  1830. +  if (opcode == 7 && nm_flags == 0x80 && rcode == 0)
  1831. +    DEBUG(3,("WAIT FOR ACKNOWLEDGEMENT RESPONSE\n"));
  1832. +  
  1833. +  if (opcode == 0 && (nm_flags&~1) == 0x00 && rcode == 0)
  1834. +    DEBUG(3,("NODE STATUS REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1835. +
  1836. +  if (opcode == 0 && nm_flags == 0x40 && rcode == 0)
  1837. +    {
  1838. +      DEBUG(3,("NODE STATUS RESPONSE\n"));
  1839. +      interpret_node_status(inbuf,NULL);
  1840. +    }
  1841. +  
  1842. +  
  1843. +  DEBUG(3,("name_trn_id=0x%x\nopcode=0x%x\nnm_flags=0x%x\nrcode=0x%x\n",
  1844. +    name_trn_id,opcode,nm_flags,rcode));
  1845. +  DEBUG(3,("qdcount=%d\nancount=%d\nnscount=%d\narcount=%d\n",
  1846. +    qdcount,ancount,nscount,arcount));
  1847. +
  1848. +  l = 12;
  1849. +  for (i=0;i<qdcount;i++)
  1850. +    {
  1851. +      int type,class;
  1852. +      DEBUG(3,("QUESTION %d\n",i));
  1853. +      name_extract(inbuf,l,name);
  1854. +      l += name_len(inbuf+l);
  1855. +      type = RSVAL(inbuf+l,0);
  1856. +      class = RSVAL(inbuf+l,2);
  1857. +      l += 4;
  1858. +      DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
  1859. +    }
  1860. +
  1861. +  for (i=0;i<(ancount + nscount + arcount);i++)
  1862. +    {
  1863. +      int type,class,ttl,rdlength;
  1864. +      DEBUG(3,("RESOURCE %d\n",i));
  1865. +      name_extract(inbuf,l,name);
  1866. +      l += name_len(inbuf + l);
  1867. +      type = RSVAL(inbuf+l,0);
  1868. +      class = RSVAL(inbuf+l,2);
  1869. +      ttl = RIVAL(inbuf+l,4);
  1870. +      rdlength = RSVAL(inbuf+l,8);
  1871. +      l += 10 + rdlength;
  1872. +      DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
  1873. +      DEBUG(3,("\tttl=%d\n\trdlength=%d\n",ttl,rdlength));
  1874. +    }
  1875. +
  1876. +  DEBUG(3,("\n"));
  1877. +  
  1878. +}
  1879. +
  1880. +
  1881. +/****************************************************************************
  1882. +do a netbios name status to a host
  1883. +****************************************************************************/
  1884. +static BOOL name_status(char *name,int type,struct in_addr to_ip,char *master)
  1885. +{
  1886. +  pstring inbuf,outbuf;
  1887. +  static uint16 name_trn_id = 0x4262;
  1888. +  char *p;
  1889. +  int retries = 2;
  1890. +  int retry_time = 5000;
  1891. +  struct timeval tval;
  1892. +
  1893. +  bzero(inbuf,sizeof(inbuf));
  1894. +  bzero(outbuf,sizeof(outbuf));
  1895. +
  1896. +  name_trn_id += getpid() % 100;
  1897. +  name_trn_id = (name_trn_id % 10000);
  1898. +
  1899. +  RSSVAL(outbuf,0,name_trn_id);
  1900. +  CVAL(outbuf,2) = 0;
  1901. +  CVAL(outbuf,3) = 0x0;
  1902. +  RSSVAL(outbuf,4,1);
  1903. +  RSSVAL(outbuf,6,0);
  1904. +  RSSVAL(outbuf,8,0);
  1905. +  RSSVAL(outbuf,10,0);  
  1906. +  p = outbuf+12;
  1907. +  name_mangle(name,p,type);
  1908. +  p += name_len(p);
  1909. +  RSSVAL(p,0,0x21);
  1910. +  RSSVAL(p,2,0x1);
  1911. +  p += 4;
  1912. +
  1913. +  show_nmb(outbuf);
  1914. +
  1915. +  GetTimeOfDay(&tval);
  1916. +
  1917. +  if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
  1918. +    return False;
  1919. +  
  1920. +  while (1)
  1921. +    {
  1922. +      struct timeval tval2;
  1923. +      GetTimeOfDay(&tval2);
  1924. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  1925. +    if (!retries) break;
  1926. +    if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
  1927. +      return False;
  1928. +    GetTimeOfDay(&tval);
  1929. +    retries--;    
  1930. +      }
  1931. +      
  1932. +      if (receive_nmb(inbuf,90))
  1933. +    {
  1934. +      int rec_name_trn_id = RSVAL(inbuf,0);
  1935. +      int rcode = CVAL(inbuf,3) & 0xF;
  1936. +      int response = (CVAL(inbuf,2)>>7);
  1937. +      int qdcount = RSVAL(inbuf,4);
  1938. +      int ancount = RSVAL(inbuf,6);
  1939. +
  1940. +      show_nmb(inbuf);
  1941. +      
  1942. +      /* is it a positive response to our request? */
  1943. +      if (response && (rec_name_trn_id == name_trn_id)) {
  1944. +        if (rcode==0 && ancount==1 && qdcount==0) {
  1945. +          interpret_node_status(inbuf, master);
  1946. +          return(True);
  1947. +        }
  1948. +        return(False);
  1949. +      }
  1950. +    }
  1951. +    }
  1952. +
  1953. +  DEBUG(0,("No status response (this is not unusual)\n"));
  1954. +
  1955. +  return(False);
  1956. +}
  1957. +
  1958. +/****************************************************************************
  1959. +construct a host announcement unicast
  1960. +****************************************************************************/
  1961. +static BOOL send_udp_dgram(char *buf,int len,
  1962. +             char *srcname,char *dstname,
  1963. +             int src_type,int dest_type,
  1964. +             struct in_addr dest_ip)
  1965. +{
  1966. +  pstring outbuf;
  1967. +  char *p,*p2;
  1968. +  static int id=0;
  1969. +  char tmp[4];
  1970. +  struct sockaddr_in sock_out;
  1971. +
  1972. +  bzero(outbuf,sizeof(outbuf));
  1973. +  RSSVAL(outbuf,0,0x1102); /* what is this? */
  1974. +  RSSVAL(outbuf,2,++id); 
  1975. +  putip(outbuf+4,(void *)&myip);
  1976. +  RSSVAL(outbuf,8,DGRAM_PORT);
  1977. +  RSSVAL(outbuf,12,0);
  1978. +  p = outbuf + 14;
  1979. +  p += name_mangle(srcname,p,src_type);
  1980. +  p += name_mangle(dstname,p,dest_type);
  1981. +
  1982. +  /* now setup the smb part */
  1983. +  p -= 4;
  1984. +  memcpy(tmp,p,4);
  1985. +  set_message(p,17,17 + len,True);
  1986. +  memcpy(p,tmp,4);
  1987. +
  1988. +  CVAL(p,smb_com) = SMBtrans;
  1989. +  SSVAL(p,smb_vwv1,len);
  1990. +  SSVAL(p,smb_vwv11,len);
  1991. +  SSVAL(p,smb_vwv12,86);
  1992. +  SSVAL(p,smb_vwv13,3);
  1993. +  SSVAL(p,smb_vwv14,1);
  1994. +  SSVAL(p,smb_vwv15,1);
  1995. +  SSVAL(p,smb_vwv16,2);
  1996. +  p2 = smb_buf(p);
  1997. +  strcpy(p2,"\\MAILSLOT\\BROWSE");
  1998. +  p2 = skip_string(p2,1);
  1999. +
  2000. +  memcpy(p2,buf,len);
  2001. +  p2 += len;
  2002. +
  2003. +  len = PTR_DIFF(p2,outbuf);
  2004. +  RSSVAL(outbuf,10,len);
  2005. +
  2006. +
  2007. +  /* set the address and port */
  2008. +  bzero((char *)&sock_out,sizeof(sock_out));
  2009. +  putip((char *)&sock_out.sin_addr,(char *)&dest_ip);
  2010. +  sock_out.sin_port = htons(DGRAM_PORT);
  2011. +  sock_out.sin_family = AF_INET;
  2012. +  
  2013. +  /* log the packet */
  2014. +  log_out(outbuf,len);
  2015. +  
  2016. +  /* send it */
  2017. +  if (sendto(ClientDGRAM,outbuf,len,0,
  2018. +         (struct sockaddr *)&sock_out,sizeof(sock_out)) < 0) {
  2019. +    DEBUG(3,("Sendto failed errno=%d (%s)\n",errno,strerror(errno)));
  2020. +    return(False);
  2021. +  } 
  2022. +
  2023. +  return(True);
  2024. +}
  2025. +
  2026. +/****************************************************************************
  2027. +construct a host announcement unicast
  2028. +****************************************************************************/
  2029. +static void announce_host(int i,char *my_name,char *Comment)
  2030. +{
  2031. +  static int announce_interval = 1;
  2032. +  char *group = names[i].name;
  2033. +  struct in_addr dest_ip = names[i].ip;
  2034. +  pstring outbuf;
  2035. +  char *p;
  2036. +
  2037. +  names[i].count++;
  2038. +
  2039. +  if ((names[i].count % announce_interval) != 0) return;
  2040. +
  2041. +  if (announce_interval < 2) announce_interval++;
  2042. +
  2043. +  DEBUG(2,("Sending host announcement to %s for group %s\n",
  2044. +       inet_ntoa(dest_ip),group));       
  2045. +
  2046. +  if (!*Comment) Comment = "NoComment";
  2047. +  if (!*my_name) my_name = "NoName";
  2048. +  if (!*group) group = "NoGroup";
  2049. +
  2050. +  if (strlen(Comment) > 47) Comment[47] = 0;  
  2051. +
  2052. +  bzero(outbuf,sizeof(outbuf));
  2053. +  p = outbuf;
  2054. +  CVAL(p,0) = 1; /* host announce */
  2055. +  SSVAL(p,1,0x6006); /* update count?? */
  2056. +  CVAL(p,3) = 0xEA; /* res1 */ 
  2057. +  SSVAL(p,4,announce_interval);
  2058. +  p += 6;
  2059. +  StrnCpy(p,my_name,16);
  2060. +  strupper(p);
  2061. +  p += 16;
  2062. +  CVAL(p,0) = 1; /* major version (was 1) */
  2063. +  CVAL(p,1) = 0x33; /* minor version (was 51) */
  2064. +  SIVAL(p,2,0xB03); /* server and w'station + unix + printq + domain member*/
  2065. +  SSVAL(p,6,0x30B); /* election version */
  2066. +  SSVAL(p,8,0xAA55); /* browse constant */
  2067. +  p += 10;
  2068. +  strcpy(p,Comment);
  2069. +  p += strlen(p)+1;
  2070. +
  2071. +  send_udp_dgram(outbuf,PTR_DIFF(p,outbuf),my_name,group,0,0x1d,dest_ip);
  2072. +}
  2073. +
  2074. +
  2075. +
  2076. +/****************************************************************************
  2077. +send a name registration packet
  2078. +****************************************************************************/
  2079. +static void send_registration(char *name,int name_type,struct in_addr dest_ip,struct in_addr ip,BOOL refresh,int ttl)
  2080. +{
  2081. +  char *p;
  2082. +  static int t = 0x176;
  2083. +  pstring outbuf;
  2084. +  bzero(outbuf,sizeof(outbuf));
  2085. +  /* send a registration request */
  2086. +  RSSVAL(outbuf,0,t++);
  2087. +  if (refresh)
  2088. +    CVAL(outbuf,2) = (0<<7) | (9<<3) | 0;
  2089. +  else
  2090. +    CVAL(outbuf,2) = (0<<7) | (5<<3) | 1;
  2091. +    
  2092. +  CVAL(outbuf,3) = (1<<4);
  2093. +  RSSVAL(outbuf,4,1);
  2094. +  RSSVAL(outbuf,6,0);
  2095. +  RSSVAL(outbuf,8,0);
  2096. +  RSSVAL(outbuf,10,1);  
  2097. +  p = outbuf+12;
  2098. +  name_mangle(name,p,name_type);
  2099. +  p += name_len(p);
  2100. +  RSSVAL(p,0,0x20);
  2101. +  RSSVAL(p,2,0x1);
  2102. +  p += 4;
  2103. +  RSSVAL(p,0,12);
  2104. +  CVAL(p,0) = CVAL(p,0) | 0xC0;
  2105. +  p += 2;
  2106. +  RSSVAL(p,0,0x20);
  2107. +  RSSVAL(p,2,0x1);
  2108. +  p += 4;  
  2109. +  RSIVAL(p,0,ttl);
  2110. +
  2111. +  RSSVAL(p,4,6);
  2112. +  RSSVAL(p,6,0);  
  2113. +  p += 8;
  2114. +  putip(p,&ip);  
  2115. +  p += 4;
  2116. +
  2117. +  DEBUG(2,("Sending a name registration request\n"));
  2118. +  if (DEBUGLEVEL > 2)
  2119. +    show_nmb(outbuf);
  2120. +
  2121. +  send_nmb(outbuf,PTR_DIFF(p,outbuf),&dest_ip,NMB_PORT);
  2122. +}
  2123. +
  2124. +/*******************************************************************
  2125. +find a master browser
  2126. +********************************************************************/
  2127. +BOOL find_master(char *name1,struct in_addr ip,struct in_addr *ipout)
  2128. +{
  2129. +  int type = 0x1d;
  2130. +  fstring name;
  2131. +  BOOL ret;
  2132. +  strcpy(name,name1);
  2133. +  if (strequal(name,"*")) {
  2134. +    strcpy(name,"\001\002__MSBROWSE__\002");
  2135. +    type = 1;
  2136. +  }
  2137. +  ret = name_query(name,type,True,False,ip,ipout);
  2138. +  if (!ret) return(False);
  2139. +  if (type != 1) return(True);
  2140. +
  2141. +  name_status(name,type,*ipout,name1);
  2142. +  return(name1[0] != '*');
  2143. +}
  2144. +
  2145. +/****************************************************************************
  2146. +process a workgroup announce frame
  2147. +****************************************************************************/
  2148. +static void process_workgroup_announce(char *group,struct in_addr ip)
  2149. +{
  2150. +  int i;
  2151. +  for (i=0;i<num_names;i++)
  2152. +    if (names[i].valid) {
  2153. +      if (names[i].name[0] == '*') {
  2154. +    StrnCpy(names[i].name,group,15);
  2155. +    names[i].master_ip = ip;
  2156. +    names[i].found_master = True;
  2157. +    names[i].count=0;
  2158. +    announce_host(i,myname,comment);
  2159. +    return;
  2160. +      }
  2161. +      if (names[i].isgroup && name_equal(names[i].name,group,0,0)) {
  2162. +    int j;
  2163. +    for (j=i;j<num_names;j++)
  2164. +      if (names[j].valid && names[j].isgroup && names[i].found_master && 
  2165. +          name_equal(names[i].name,group,0,0)) return;
  2166. +    names[i].master_ip = ip;
  2167. +    names[i].found_master = True;
  2168. +    names[i].count=0;
  2169. +    announce_host(i,myname,comment);
  2170. +    return;
  2171. +      }
  2172. +    }
  2173. +}
  2174. +
  2175. +
  2176. +/****************************************************************************
  2177. +process a browse frame
  2178. +****************************************************************************/
  2179. +static void process_browse_packet(char *buf,int len)
  2180. +{
  2181. +  char *p;
  2182. +  int command = CVAL(buf,0);
  2183. +  switch (command) {
  2184. +  case 0xc: /* workgroup announcement */
  2185. +    {
  2186. +      fstring group;
  2187. +      p = buf + 6;
  2188. +      StrnCpy(group,p,15);
  2189. +      DEBUG(2,("Got workgroup announce for %s (%s)\n",
  2190. +           group,inet_ntoa(lastip)));
  2191. +      process_workgroup_announce(group,lastip);
  2192. +      break;
  2193. +    }
  2194. +  }
  2195. +
  2196. +}
  2197. +
  2198. +/****************************************************************************
  2199. +process udp 138 datagrams
  2200. +****************************************************************************/
  2201. +static void process_dgram(void)
  2202. +{
  2203. +  pstring inbuf;
  2204. +  int len;
  2205. +  while (read_max_udp(ClientDGRAM,inbuf,sizeof(inbuf),1) > 4) {
  2206. +    char *p = inbuf;
  2207. +    len = RSVAL(inbuf,10);
  2208. +    p += 14;
  2209. +    p += name_len(p);
  2210. +    p += name_len(p);
  2211. +    p -= 4;
  2212. +    if (CVAL(p,smb_com) != SMBtrans) continue;
  2213. +    if (!strequal(smb_buf(p),"\\MAILSLOT\\BROWSE")) continue;
  2214. +    len = SVAL(p,smb_vwv11);
  2215. +    p = smb_base(p) + SVAL(p,smb_vwv12);
  2216. +    if (len <= 0) continue;
  2217. +    process_browse_packet(p,len);
  2218. +  }
  2219. +}
  2220. +
  2221. +/****************************************************************************
  2222. +a hook for registration of my own names
  2223. +****************************************************************************/
  2224. +static void do_registration_hook(void)
  2225. +{
  2226. +  static int count = 0;
  2227. +  static time_t last_t=0;
  2228. +  time_t t = time(NULL);
  2229. +  
  2230. +  if (last_t && (t-last_t)<REGISTRATION_INTERVAL) return;
  2231. +  last_t = t;
  2232. +  
  2233. +  send_registration(myname,0x20,bcast_ip,myip,count>0,300000);
  2234. +  count++;
  2235. +}
  2236. +
  2237. +/****************************************************************************
  2238. +a hook for browsing handling - called every BROWSE_INTERVAL secs
  2239. +****************************************************************************/
  2240. +static void do_browse_hook(void)
  2241. +{
  2242. +  static BOOL first = True;
  2243. +  int i;
  2244. +  static time_t last_t=0;
  2245. +  time_t t = time(NULL);
  2246. +  
  2247. +  if (last_t && (t-last_t)<browse_interval) return;
  2248. +  last_t = t;
  2249. +
  2250. +  for (i=0;i<num_names;i++)
  2251. +    {
  2252. +      BOOL old_found_master = names[i].found_master;
  2253. +
  2254. +      if (!NAMEVALID(i) || !ISGROUP(i)) continue;
  2255. +
  2256. +      if (names[i].found_master) {
  2257. +    struct in_addr ip2;
  2258. +    announce_host(i,myname,comment);
  2259. +
  2260. +    if (!name_query(names[i].name,0x1d,True,False,
  2261. +            names[i].master_ip,
  2262. +            &ip2)) {
  2263. +      DEBUG(2,("%s Master browser at %s failed to respond\n",
  2264. +           timestring(),
  2265. +           inet_ntoa(names[i].master_ip)));
  2266. +      names[i].found_master = False;
  2267. +    } else {
  2268. +      names[i].master_ip = ip2;
  2269. +    }
  2270. +      }
  2271. +
  2272. +      if (!names[i].found_master) {
  2273. +    struct in_addr ip2;
  2274. +    names[i].found_master = find_master(names[i].name,names[i].ip,&ip2);
  2275. +
  2276. +    if (names[i].found_master) {
  2277. +      names[i].master_ip = ip2;
  2278. +      DEBUG(1,("%s New master browser for %s at %s\n",
  2279. +           timestring(),
  2280. +           names[i].name,inet_ntoa(names[i].master_ip)));
  2281. +      names[i].count = 0;
  2282. +      announce_host(i,myname,comment);
  2283. +    }
  2284. +      }
  2285. +
  2286. +      if (!names[i].found_master) {
  2287. +    int level = (old_found_master||first)?1:2;
  2288. +    DEBUG(level,("%s Failed to find a master browser for %s using %s\n",
  2289. +             timestring(),
  2290. +             names[i].name,inet_ntoa(names[i].ip)));
  2291. +      }
  2292. +    }
  2293. +  first = False;
  2294. +}
  2295. +
  2296. +
  2297. +/****************************************************************************
  2298. +  do a netbios name query to find someones IP
  2299. +  ****************************************************************************/
  2300. +static BOOL name_query(char *name,int name_type, BOOL bcast,BOOL recurse,
  2301. +               struct in_addr to_ip, struct in_addr *ip)
  2302. +{
  2303. +  BOOL found=False;
  2304. +  static uint16 name_trn_id = 0;
  2305. +  int retries = 3;
  2306. +  int retry_time = bcast?250:5000;
  2307. +  struct timeval tval;
  2308. +  struct packet_struct p;
  2309. +  struct packet_struct *p2;
  2310. +  struct nmb_packet *nmb = &p.packet.nmb;
  2311. +
  2312. +  bzero((char *)&p,sizeof(p));
  2313. +
  2314. +  if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
  2315. +  name_trn_id = (name_trn_id+1) % 0x7FFF;
  2316. +
  2317. +  nmb->header.name_trn_id = name_trn_id;
  2318. +  nmb->header.opcode = 0;
  2319. +  nmb->header.response = False;
  2320. +  nmb->header.nm_flags.bcast = bcast;
  2321. +  nmb->header.nm_flags.recursion_available = CanRecurse;
  2322. +  nmb->header.nm_flags.recursion_desired = recurse;
  2323. +  nmb->header.nm_flags.trunc = False;
  2324. +  nmb->header.nm_flags.authoritative = False;
  2325. +  nmb->header.rcode = 0;
  2326. +  nmb->header.qdcount = 1;
  2327. +  nmb->header.ancount = 0;
  2328. +  nmb->header.nscount = 0;
  2329. +  nmb->header.arcount = 0;
  2330. +
  2331. +  strcpy(nmb->question.question_name.name,name);
  2332. +  strupper(nmb->question.question_name.name);
  2333. +  nmb->question.question_name.name_type = name_type;
  2334. +  strcpy(nmb->question.question_name.scope,scope);
  2335. +
  2336. +  nmb->question.question_type = 0x20;
  2337. +  nmb->question.question_class = 0x1;
  2338. +
  2339. +  p.ip = to_ip;
  2340. +  p.port = NMB_PORT;
  2341. +  p.fd = ClientNMB;
  2342. +  p.timestamp = time(NULL);
  2343. +  p.packet_type = NMB_PACKET;
  2344. +
  2345. +  GetTimeOfDay(&tval);
  2346. +
  2347. +  if (!send_packet(&p)) 
  2348. +    return(False);
  2349. +
  2350. +  retries--;
  2351. +
  2352. +  while (1)
  2353. +    {
  2354. +      struct timeval tval2;
  2355. +      GetTimeOfDay(&tval2);
  2356. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  2357. +    if (!retries) break;
  2358. +    if (!found && !send_packet(&p))
  2359. +      return False;
  2360. +    GetTimeOfDay(&tval);
  2361. +    retries--;
  2362. +      }
  2363. +
  2364. +      if ((p2=receive_packet(ClientNMB,NMB_PACKET,90)))
  2365. +    {     
  2366. +      struct nmb_packet *nmb2 = &p2->packet.nmb;
  2367. +      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  2368. +          !nmb2->header.response) {
  2369. +        /* its not for us - deal with it later */
  2370. +        queue_packet(p2);
  2371. +        continue;
  2372. +      }
  2373. +      
  2374. +      if (nmb2->header.opcode != 0 ||
  2375. +          nmb2->header.nm_flags.bcast ||
  2376. +          nmb2->header.rcode ||
  2377. +          !nmb2->header.ancount) {
  2378. +        /* XXXX what do we do with this? could be a redirect, but
  2379. +           we'll discard it for the moment */
  2380. +        free_packet(p2);
  2381. +        continue;
  2382. +      }
  2383. +
  2384. +      putip((char *)ip,&nmb2->answers->rdata[2]);
  2385. +      DEBUG(2,("Got a positive name query response from %s",
  2386. +           inet_ntoa(p2->ip)));
  2387. +      DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
  2388. +      found=True; retries=0;
  2389. +    }
  2390. +    }
  2391. +
  2392. +  return(found);
  2393. +}
  2394. +
  2395. +
  2396. +/****************************************************************************
  2397. +reply to a name release
  2398. +****************************************************************************/
  2399. +static void reply_name_release(struct packet_struct *p)
  2400. +{
  2401. +  struct nmb_packet *nmb = &p->packet.nmb;
  2402. +  char *qname = nmb->question.question_name.name;
  2403. +  BOOL wildcard = (qname[0] == '*'); 
  2404. +  int name_type = nmb->question.question_name.name_type;
  2405. +  int nb_flags = nmb->additional->rdata[0];
  2406. +  struct packet_struct p2;
  2407. +  struct nmb_packet *nmb2;
  2408. +  struct res_rec answer_rec;
  2409. +  struct in_addr ip;
  2410. +  BOOL release_ok=False;
  2411. +  int reason=5;
  2412. +  int n;
  2413. +
  2414. +  if (wildcard) return;
  2415. +
  2416. +  putip((char *)&ip,&nmb->additional->rdata[2]);  
  2417. +
  2418. +  n = find_name(qname,name_type,True);
  2419. +  if (n>=0 && names[n].source == REGISTER &&
  2420. +      !memcmp((char *)&ip,(char *)&names[n].ip,sizeof(ip))) {
  2421. +    release_ok = True;
  2422. +    names[n].valid = False;
  2423. +  }
  2424. +
  2425. +  /* Send a POSITIVE NAME RELEASE RESPONSE */
  2426. +  p2 = *p;
  2427. +  nmb2 = &p2.packet.nmb;
  2428. +
  2429. +  nmb2->header.response = True;
  2430. +  nmb2->header.nm_flags.bcast = False;
  2431. +  nmb2->header.nm_flags.recursion_available = CanRecurse;
  2432. +  nmb2->header.nm_flags.trunc = False;
  2433. +  nmb2->header.nm_flags.authoritative = True; 
  2434. +  nmb2->header.qdcount = 0;
  2435. +  nmb2->header.ancount = 1;
  2436. +  nmb2->header.nscount = 0;
  2437. +  nmb2->header.arcount = 0;
  2438. +  nmb2->header.rcode = release_ok?0:reason;
  2439. +
  2440. +  nmb2->answers = &answer_rec;
  2441. +  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  2442. +  
  2443. +  nmb2->answers->rr_name = nmb->question.question_name;
  2444. +  nmb2->answers->rr_type = nmb->question.question_type;
  2445. +  nmb2->answers->rr_class = nmb->question.question_class;
  2446. +  nmb2->answers->ttl = 0; 
  2447. +  nmb2->answers->rdlength = 6;
  2448. +  nmb2->answers->rdata[0] = nb_flags;
  2449. +  putip(&nmb2->answers->rdata[2],(char *)&ip);
  2450. +
  2451. +  send_packet(&p2);
  2452. +}
  2453. +
  2454. +
  2455. +
  2456. +/****************************************************************************
  2457. +  reply to a reg request
  2458. +  **************************************************************************/
  2459. +static void reply_name_reg(struct packet_struct *p)
  2460. +{
  2461. +  struct nmb_packet *nmb = &p->packet.nmb;
  2462. +  char *qname = nmb->question.question_name.name;
  2463. +  BOOL wildcard = (qname[0] == '*'); 
  2464. +  BOOL bcast = nmb->header.nm_flags.bcast;
  2465. +  int name_type = nmb->question.question_name.name_type;
  2466. +  int ttl = nmb->additional->ttl;
  2467. +  int nb_flags = nmb->additional->rdata[0];
  2468. +  struct packet_struct p2;
  2469. +  struct nmb_packet *nmb2;
  2470. +  struct res_rec answer_rec;
  2471. +  struct in_addr ip;
  2472. +
  2473. +  if (wildcard) return;
  2474. +
  2475. +  putip((char *)&ip,&nmb->additional->rdata[2]);
  2476. +
  2477. +  if ((nb_flags&0x80) == 0 && (name_type != 0x1d)) {
  2478. +    int n = find_name(qname,name_type,True);
  2479. +    if (ttl==0) ttl = NMBD_MAX_TTL;
  2480. +    ttl = MIN(ttl,NMBD_MAX_TTL);
  2481. +
  2482. +    if (n>=0 && names[n].source != REGISTER && names[n].source != DNS)
  2483. +      return;
  2484. +
  2485. +    if (n<0)
  2486. +      n = add_name();
  2487. +    if (n<0) return;
  2488. +
  2489. +    bzero(&names[n],sizeof(names[n]));
  2490. +
  2491. +    StrnCpy(names[n].name,qname,15);
  2492. +    names[n].type = name_type;
  2493. +    names[n].unicast = !dns_serve || is_mynet(ip);
  2494. +    names[n].ip = ip;
  2495. +    names[n].valid = True;
  2496. +    names[n].ttl = ttl;
  2497. +    names[n].source = REGISTER;
  2498. +    names[n].start_time = p->timestamp;
  2499. +  }
  2500. +
  2501. +  if (bcast) return;
  2502. +
  2503. +  /* Send a POSITIVE NAME REGISTRATION RESPONSE */
  2504. +  /* a lot of fields get copied from the query. This gives us the IP
  2505. +     and port the reply will be sent to etc */
  2506. +  p2 = *p;
  2507. +  nmb2 = &p2.packet.nmb;
  2508. +
  2509. +  nmb2->header.response = True;
  2510. +  nmb2->header.nm_flags.bcast = False;
  2511. +  nmb2->header.nm_flags.recursion_available = CanRecurse;
  2512. +  nmb2->header.nm_flags.trunc = False;
  2513. +  nmb2->header.nm_flags.authoritative = True; 
  2514. +  nmb2->header.qdcount = 0;
  2515. +  nmb2->header.ancount = 1;
  2516. +  nmb2->header.nscount = 0;
  2517. +  nmb2->header.arcount = 0;
  2518. +
  2519. +  nmb2->answers = &answer_rec;
  2520. +  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  2521. +  
  2522. +  nmb2->answers->rr_name = nmb->question.question_name;
  2523. +  nmb2->answers->rr_type = nmb->question.question_type;
  2524. +  nmb2->answers->rr_class = nmb->question.question_class;
  2525. +
  2526. +  /* we want them to refresh in case we die */
  2527. +  if (!ttl) ttl = 15*60;
  2528. +  ttl = MIN(ttl,15*60);
  2529. +
  2530. +  nmb2->answers->ttl = ttl; 
  2531. +  nmb2->answers->rdlength = 6;
  2532. +  nmb2->answers->rdata[0] = nb_flags;
  2533. +  putip(&nmb2->answers->rdata[2],(char *)&ip);
  2534. +
  2535. +  send_packet(&p2);  
  2536. +}
  2537. +
  2538. +
  2539. +/****************************************************************************
  2540. +reply to a name status query
  2541. +****************************************************************************/
  2542. +static void reply_name_status(struct packet_struct *p)
  2543. +{
  2544. +  struct nmb_packet *nmb = &p->packet.nmb;
  2545. +  char *qname = nmb->question.question_name.name;
  2546. +  BOOL wildcard = (qname[0] == '*'); 
  2547. +  int name_type = nmb->question.question_name.name_type;
  2548. +  struct packet_struct p2;
  2549. +  struct nmb_packet *nmb2;
  2550. +  struct res_rec answer_rec;
  2551. +  char *buf;
  2552. +  int count,i;
  2553. +
  2554. +  if (!wildcard) {
  2555. +    i = find_name(qname,name_type,False);
  2556. +
  2557. +    if (i < 0)
  2558. +      return;
  2559. +    if (names[i].source != SELF && names[i].source != LMHOSTS)
  2560. +      return;
  2561. +  }
  2562. +
  2563. +  /* Send a POSITIVE NAME STATUS RESPONSE */
  2564. +  /* a lot of fields get copied from the query. This gives us the IP
  2565. +     and port the reply will be sent to etc */
  2566. +  p2 = *p;
  2567. +  nmb2 = &p2.packet.nmb;
  2568. +
  2569. +  nmb2->header.response = True;
  2570. +  nmb2->header.nm_flags.bcast = False;
  2571. +  nmb2->header.nm_flags.recursion_available = CanRecurse;
  2572. +  nmb2->header.nm_flags.trunc = False;
  2573. +  nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
  2574. +                         non-authoritative answers */
  2575. +  nmb2->header.qdcount = 0;
  2576. +  nmb2->header.ancount = 1;
  2577. +  nmb2->header.nscount = 0;
  2578. +  nmb2->header.arcount = 0;
  2579. +
  2580. +  nmb2->answers = &answer_rec;
  2581. +  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  2582. +  
  2583. +
  2584. +  nmb2->answers->rr_name = nmb->question.question_name;
  2585. +  nmb2->answers->rr_type = nmb->question.question_type;
  2586. +  nmb2->answers->rr_class = nmb->question.question_class;
  2587. +  nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
  2588. +
  2589. +  for (count=0,i=0;i<num_names;i++)
  2590. +    if (names[i].valid) count++;
  2591. +  count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
  2592. +                how many will fit */
  2593. +
  2594. +  
  2595. +  buf = &nmb2->answers->rdata[0];
  2596. +  SCVAL(buf,0,count);
  2597. +  buf += 1;
  2598. +
  2599. +  for (i=0;i<num_names && count>0;i++)
  2600. +    if (names[i].valid)
  2601. +      {
  2602. +    bzero(buf,18);
  2603. +    strcpy(buf,names[i].name);
  2604. +    strupper(buf);
  2605. +    buf[15] = names[i].type;
  2606. +    buf += 16;
  2607. +    buf[0] = 0x4; /* active */
  2608. +    if (strequal(names[i].name,myname)) buf[0] |= 0x2; /* permanent */
  2609. +    if (ISGROUP(i)) buf[0] |= 0x80; /* group */
  2610. +    buf += 2;
  2611. +    count--;
  2612. +      }
  2613. +
  2614. +  /* we should fill in more fields of the statistics structure */
  2615. +  bzero(buf,46);
  2616. +  putip(buf,(char *)&myip);
  2617. +  {
  2618. +    extern int num_good_sends,num_good_receives;
  2619. +    SIVAL(buf,20,num_good_sends);
  2620. +    SIVAL(buf,24,num_good_receives);
  2621. +  }
  2622. +
  2623. +  buf += 46;
  2624. +
  2625. +  nmb2->answers->rdlength = PTR_DIFF(buf,&nmb2->answers->rdata[0]);
  2626. +
  2627. +  send_packet(&p2);
  2628. +}
  2629. +
  2630. +
  2631. +
  2632. +/****************************************************************************
  2633. +reply to a name query
  2634. +****************************************************************************/
  2635. +static void reply_name_query(struct packet_struct *p)
  2636. +{
  2637. +  struct nmb_packet *nmb = &p->packet.nmb;
  2638. +  char *qname = nmb->question.question_name.name;
  2639. +  BOOL wildcard = (qname[0] == '*'); 
  2640. +  BOOL bcast = nmb->header.nm_flags.bcast;
  2641. +  struct in_addr retip;
  2642. +  int name_type = nmb->question.question_name.name_type;
  2643. +  struct packet_struct p2;
  2644. +  struct nmb_packet *nmb2;
  2645. +  struct res_rec answer_rec;
  2646. +
  2647. +  if (!wildcard) {
  2648. +    int i = find_name(qname,name_type,False);
  2649. +
  2650. +    if (i < 0)
  2651. +      i = find_name(qname,name_type,True);
  2652. +    
  2653. +    if (i >= 0)
  2654. +      {
  2655. +    if (bcast && (names[i].unicast || names[i].source == REGISTER))
  2656. +      return;
  2657. +  
  2658. +    if (ISGROUP(i))
  2659. +      return;
  2660. +
  2661. +    retip = names[i].ip;
  2662. +      }
  2663. +    else
  2664. +      {
  2665. +    if ((name_type!=0 && name_type!=0x3 && name_type!=0x20) ||
  2666. +        (bcast && !dns_serve)) {
  2667. +      return;
  2668. +    } else {
  2669. +      unsigned long a;
  2670. +
  2671. +      a = interpret_addr(qname);
  2672. +      if (!a) return;
  2673. +
  2674. +      /* here is where we might recurse */      
  2675. +      putip((char *)&retip,(char *)&a);
  2676. +        
  2677. +      if (bcast && is_mynet(retip))
  2678. +        return;
  2679. +
  2680. +      i = find_name(qname,name_type,True);
  2681. +      if (i < 0) {
  2682. +        if ((i=add_name())>=0) {
  2683. +          StrnCpy(names[i].name,qname,15);
  2684. +          names[i].type = name_type;
  2685. +          names[i].unicast = is_mynet(retip);
  2686. +          names[i].ip = retip;
  2687. +          names[i].valid = True;
  2688. +          names[i].ttl = 120; /* give it two minutes */
  2689. +          names[i].start_time = p->timestamp;
  2690. +          names[i].source = DNS;        
  2691. +        }
  2692. +      }
  2693. +    }
  2694. +    DEBUG(2,(" sending positive reply (%s)\n",inet_ntoa(retip)));
  2695. +      }
  2696. +  } else {
  2697. +    retip = myip;
  2698. +  }
  2699. +  
  2700. +
  2701. +  /* a lot of fields get copied from the query. This gives us the IP
  2702. +     and port the reply will be sent to etc */
  2703. +  p2 = *p;
  2704. +  nmb2 = &p2.packet.nmb;
  2705. +
  2706. +  nmb2->header.response = True;
  2707. +  nmb2->header.nm_flags.bcast = False;
  2708. +  nmb2->header.nm_flags.recursion_available = CanRecurse;
  2709. +  nmb2->header.nm_flags.trunc = False;
  2710. +  nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
  2711. +                         non-authoritative answers */
  2712. +  nmb2->header.qdcount = 0;
  2713. +  nmb2->header.ancount = 1;
  2714. +  nmb2->header.nscount = 0;
  2715. +  nmb2->header.arcount = 0;
  2716. +
  2717. +  nmb2->answers = &answer_rec;
  2718. +  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  2719. +
  2720. +  nmb2->answers->rr_name = nmb->question.question_name;
  2721. +  nmb2->answers->rr_type = nmb->question.question_type;
  2722. +  nmb2->answers->rr_class = nmb->question.question_class;
  2723. +  nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
  2724. +  nmb2->answers->rdlength = 6;
  2725. +  nmb2->answers->rdata[0] = 0; /* XXXX nbflags - what should this be? */
  2726. +  nmb2->answers->rdata[1] = 0; 
  2727. +  putip(&nmb2->answers->rdata[2],(char *)&retip);
  2728. +
  2729. +  send_packet(&p2);
  2730. +}
  2731. +
  2732. +
  2733. +
  2734. +/* the global packet linked-list. incoming entries are added to the
  2735. +   end of this list.  it is supposed to remain fairly short so we
  2736. +   won't bother with an end pointer. */
  2737. +static struct packet_struct *packet_queue = NULL;
  2738. +
  2739. +
  2740. +/*******************************************************************
  2741. +  queue a packet into the packet queue
  2742. +  ******************************************************************/
  2743. +static void queue_packet(struct packet_struct *packet)
  2744. +{
  2745. +  struct packet_struct *p;
  2746. +  if (!packet_queue) {
  2747. +    packet->prev = NULL;
  2748. +    packet->next = NULL;
  2749. +    packet_queue = packet;
  2750. +    return;
  2751. +  }
  2752. +  
  2753. +  /* find the bottom */
  2754. +  for (p=packet_queue;p->next;p=p->next) ;
  2755. +
  2756. +  p->next = packet;
  2757. +  packet->next = NULL;
  2758. +  packet->prev = p;
  2759. +}
  2760. +
  2761. +/****************************************************************************
  2762. +  process a nmb packet
  2763. +  ****************************************************************************/
  2764. +static void process_nmb(struct packet_struct *p)
  2765. +{
  2766. +  struct nmb_packet *nmb = &p->packet.nmb;
  2767. +
  2768. +  /* if this is a response then ignore it */
  2769. +  if (nmb->header.response) return;
  2770. +  
  2771. +  if (!nmb->header.nm_flags.bcast && 
  2772. +      nmb->header.opcode == 0x5 && 
  2773. +      nmb->header.qdcount==1 && 
  2774. +      nmb->header.arcount==1)
  2775. +    {
  2776. +      reply_name_reg(p);
  2777. +      return;
  2778. +    }
  2779. +
  2780. +  if (nmb->header.opcode==0 && 
  2781. +      nmb->header.qdcount==1)
  2782. +    {
  2783. +      switch (nmb->question.question_type)
  2784. +    {
  2785. +    case 0x20:
  2786. +      reply_name_query(p);
  2787. +      break;
  2788. +
  2789. +    case 0x21:
  2790. +      reply_name_status(p);
  2791. +      break;
  2792. +    }
  2793. +      return;
  2794. +    }
  2795. +
  2796. +  if (!nmb->header.nm_flags.bcast && 
  2797. +      nmb->header.opcode == 6 && 
  2798. +      nmb->header.qdcount==1 && 
  2799. +      nmb->header.arcount==1)
  2800. +    {
  2801. +      reply_name_release(p);
  2802. +      return;
  2803. +    }
  2804. +
  2805. +  if (!nmb->header.nm_flags.bcast && 
  2806. +      ((nmb->header.opcode == 8) || (nmb->header.opcode == 9)) && 
  2807. +      nmb->header.qdcount==1 && 
  2808. +      nmb->header.arcount==1)
  2809. +    {
  2810. +      reply_name_reg(p);
  2811. +      return;
  2812. +    }
  2813. +}
  2814. +
  2815. +
  2816. +
  2817. +/*******************************************************************
  2818. +  run elements off the packet queue till its empty
  2819. +  ******************************************************************/
  2820. +static void run_packet_queue(void)
  2821. +{
  2822. +  struct packet_struct *p;
  2823. +
  2824. +  while ((p=packet_queue)) {
  2825. +    switch (p->packet_type)
  2826. +      {
  2827. +      case NMB_PACKET:
  2828. +    process_nmb(p);
  2829. +    break;
  2830. +
  2831. +      case DGRAM_PACKET:
  2832. +    /* process_dgram(p); */
  2833. +    break;
  2834. +      }
  2835. +
  2836. +    packet_queue = packet_queue->next;
  2837. +    if (packet_queue) packet_queue->prev = NULL;
  2838. +    free_packet(p);
  2839. +  }
  2840. +}
  2841. +
  2842. +
  2843. +/****************************************************************************
  2844. +  The main select loop, listen for packets and respond
  2845. +  ***************************************************************************/
  2846. +void process(void)
  2847. +{
  2848. +  while (True)
  2849. +    {
  2850. +      fd_set fds;
  2851. +      int selrtn;
  2852. +      struct timeval timeout;
  2853. +
  2854. +      do_registration_hook();
  2855. +      do_browse_hook();
  2856. +
  2857. +      FD_ZERO(&fds);
  2858. +      FD_SET(ClientNMB,&fds);
  2859. +      FD_SET(ClientDGRAM,&fds);
  2860. +      timeout.tv_sec = NMBD_SELECT_LOOP;
  2861. +      timeout.tv_usec = 0;
  2862. +
  2863. +      selrtn = sys_select(&fds,&timeout);
  2864. +
  2865. +      if (FD_ISSET(ClientNMB,&fds)) {
  2866. +    struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
  2867. +    if (packet) queue_packet(packet);
  2868. +      }
  2869. +
  2870. +      if (FD_ISSET(ClientDGRAM,&fds)) {
  2871. +    struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
  2872. +    if (packet) queue_packet(packet);
  2873. +      }
  2874. +
  2875. +      run_packet_queue();
  2876. +    }
  2877. +}
  2878. +
  2879. +
  2880. +/****************************************************************************
  2881. +  open the socket communication
  2882. +****************************************************************************/
  2883. +static BOOL open_sockets(BOOL isdaemon,int port)
  2884. +{
  2885. +  struct hostent *hp;
  2886. +  /* get host info */
  2887. +  if ((hp = Get_Hostbyname(myhostname)) == 0) 
  2888. +    {
  2889. +      DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  2890. +      return False;
  2891. +    }   
  2892. +
  2893. +  if (isdaemon)
  2894. +    ClientNMB = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
  2895. +  else
  2896. +    ClientNMB = 0;
  2897. +
  2898. +  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
  2899. +
  2900. +  if (ClientNMB == -1)
  2901. +    return(False);
  2902. +
  2903. +  signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  2904. +
  2905. +  set_socket_options(ClientNMB,"SO_BROADCAST");
  2906. +  set_socket_options(ClientDGRAM,"SO_BROADCAST");
  2907. +  set_socket_options(ClientNMB,user_socket_options);
  2908. +
  2909. +  DEBUG(3, ("Socket opened.\n"));
  2910. +  return True;
  2911. +};
  2912. +
  2913. +
  2914. +/****************************************************************************
  2915. +  initialise connect, service and file structs
  2916. +****************************************************************************/
  2917. +static BOOL init_structs(void )
  2918. +{
  2919. +  if (!get_myname(myhostname,got_myip?NULL:&myip))
  2920. +    return(False);
  2921. +
  2922. +  /* Read the broadcast address from the interface */
  2923. +  {
  2924. +    struct in_addr ip0,ip1,ip2;
  2925. +
  2926. +    ip0 = myip;
  2927. +
  2928. +    if (!(got_bcast && got_nmask))
  2929. +      {
  2930. +    get_broadcast(&ip0,&ip1,&ip2);
  2931. +
  2932. +    if (!got_myip)
  2933. +      myip = ip0;
  2934. +    
  2935. +    if (!got_bcast)
  2936. +      bcast_ip = ip1;
  2937. +    
  2938. +    if (!got_nmask)
  2939. +      Netmask = ip2;   
  2940. +      } 
  2941. +
  2942. +    DEBUG(1,("Using IP %s  ",inet_ntoa(myip))); /* core dump reported 
  2943. +                           doing this. Why?? XXXXX  */
  2944. +    DEBUG(1,("broadcast %s  ",inet_ntoa(bcast_ip)));
  2945. +    DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));    
  2946. +
  2947. +  }
  2948. +
  2949. +  if (! *myname) {
  2950. +    char *p;
  2951. +    strcpy(myname,myhostname);
  2952. +    p = strchr(myname,'.');
  2953. +    if (p) *p = 0;
  2954. +  }
  2955. +
  2956. +  add_host_name(myname,0x20,&myip);
  2957. +  add_host_name(myname,0x0,&myip);
  2958. +  add_host_name(myname,0x3,&myip);
  2959. +
  2960. +  return True;
  2961. +}
  2962. +
  2963. +/****************************************************************************
  2964. +usage on the program
  2965. +****************************************************************************/
  2966. +static void usage(char *pname)
  2967. +{
  2968. +  DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
  2969. +
  2970. +  printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
  2971. +  printf("Version %s\n",VERSION);
  2972. +  printf("\t-D                    become a daemon\n");
  2973. +  printf("\t-P                    passive only. don't respond\n");
  2974. +  printf("\t-R                    only reply to queries, don't actively send claims\n");
  2975. +  printf("\t-p port               listen on the specified port\n");
  2976. +  printf("\t-d debuglevel         set the debuglevel\n");
  2977. +  printf("\t-l log basename.      Basename for log/debug files\n");
  2978. +  printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
  2979. +  printf("\t-B broadcast address  the address to use for broadcasts\n");
  2980. +  printf("\t-N netmask           the netmask to use for subnet determination\n");
  2981. +  printf("\t-L name              lookup this netbios name then exit\n");
  2982. +  printf("\t-S                   serve queries via DNS if not on the same subnet\n");
  2983. +  printf("\t-H hosts file        load a netbios hosts file\n");
  2984. +  printf("\t-G group name        add a group name to be part of\n");
  2985. +  printf("\t-b                   toggles browsing support (defaults to on)\n");
  2986. +  printf("\t-M group name        searches for a master browser for the given group\n");
  2987. +  printf("\t-T interval          sets the browse announcement interval in seconds\n");
  2988. +  printf("\t-C comment           sets the machine comment that appears in browse lists\n");
  2989. +  printf("\n");
  2990. +}
  2991. +
  2992. +
  2993. +/****************************************************************************
  2994. +  main program
  2995. +****************************************************************************/
  2996. +int main(int argc,char *argv[])
  2997. +{
  2998. +  int port = NMB_PORT;
  2999. +  int opt;
  3000. +  unsigned int lookup_type = 0;
  3001. +  extern FILE *dbf;
  3002. +  extern char *optarg;
  3003. +
  3004. +  *lookup = *host_file = 0;
  3005. +
  3006. +  TimeInit();
  3007. +
  3008. +  charset_initialise();
  3009. +
  3010. +  strcpy(debugf,NMBLOGFILE);
  3011. +
  3012. +#ifdef LMHOSTSFILE
  3013. +  strcpy(host_file,LMHOSTSFILE);
  3014. +#endif
  3015. +
  3016. +  /* this is for people who can't start the program correctly */
  3017. +  while (argc > 1 && (*argv[1] != '-'))
  3018. +    {
  3019. +      argv++;
  3020. +      argc--;
  3021. +    }
  3022. +
  3023. +  fault_setup(fault_continue);
  3024. +
  3025. +  signal(SIGHUP,SIGNAL_CAST sig_hup);
  3026. +
  3027. +
  3028. +  while ((opt = getopt (argc, argv, "T:O:M:I:C:bAL:i:B:N:Rn:l:d:Dp:hPSH:G:")) != EOF)
  3029. +    switch (opt)
  3030. +      {
  3031. +      case 'T':
  3032. +    browse_interval = atoi(optarg);
  3033. +    browse_interval = MAX(browse_interval,10);
  3034. +    break;
  3035. +      case 'O':
  3036. +    strcpy(user_socket_options,optarg);
  3037. +    break;
  3038. +      case 'C':
  3039. +    strcpy(comment,optarg);
  3040. +    break;
  3041. +      case 'G':
  3042. +    add_group_name(optarg);
  3043. +    break;
  3044. +      case 'A':
  3045. +    dns_serve = True;
  3046. +    break;
  3047. +      case 'H':
  3048. +    strcpy(host_file,optarg);
  3049. +    break;
  3050. +      case 'I':
  3051. +    {
  3052. +      unsigned long a = interpret_addr(optarg);
  3053. +      putip((char *)&myip,(char *)&a);
  3054. +      got_myip = True;
  3055. +    }
  3056. +    break;
  3057. +      case 'B':
  3058. +    {
  3059. +      unsigned long a = interpret_addr(optarg);
  3060. +      putip((char *)&bcast_ip,(char *)&a);
  3061. +      got_bcast = True;
  3062. +    }
  3063. +    break;
  3064. +      case 'N':
  3065. +    {
  3066. +      unsigned long a = interpret_addr(optarg);
  3067. +      putip((char *)&Netmask,(char *)&a);
  3068. +      got_nmask = True;
  3069. +    }
  3070. +    break;
  3071. +      case 'n':
  3072. +    strcpy(myname,optarg);
  3073. +    break;
  3074. +      case 'P':
  3075. +    {
  3076. +      extern BOOL passive;
  3077. +      passive = True;
  3078. +    }
  3079. +    break;
  3080. +      case 'S':
  3081. +    dns_serve = !dns_serve;
  3082. +    break;
  3083. +      case 'l':
  3084. +    sprintf(debugf,"%s.nmb",optarg);
  3085. +    break;
  3086. +      case 'i':
  3087. +    strcpy(scope,optarg);
  3088. +    strupper(scope);
  3089. +    break;
  3090. +      case 'L':
  3091. +    strcpy(lookup,optarg);
  3092. +    break;
  3093. +      case 'M':
  3094. +    if (*optarg == '-') {
  3095. +      strcpy(lookup,"\01\02__MSBROWSE__\02");
  3096. +      lookup_type = 1;
  3097. +    } else {
  3098. +      strcpy(lookup,optarg);
  3099. +      lookup_type = 0x1d;
  3100. +    }
  3101. +    break;
  3102. +      case 'D':
  3103. +    is_daemon = True;
  3104. +    break;
  3105. +      case 'd':
  3106. +    DEBUGLEVEL = atoi(optarg);
  3107. +    break;
  3108. +      case 'p':
  3109. +    port = atoi(optarg);
  3110. +    break;
  3111. +      case 'h':
  3112. +    usage(argv[0]);
  3113. +    exit(0);
  3114. +    break;
  3115. +      default:
  3116. +    usage(argv[0]);
  3117. +    exit(1);
  3118. +      }
  3119. +
  3120. +  
  3121. +  if (*lookup)
  3122. +    DEBUGLEVEL++;
  3123. +  
  3124. +  if (DEBUGLEVEL > 10)
  3125. +    {
  3126. +      extern FILE *login,*logout;
  3127. +      pstring fname;
  3128. +      sprintf(fname,"%s.in",debugf);
  3129. +      login = fopen(fname,"w"); 
  3130. +      sprintf(fname,"%s.out",debugf);
  3131. +      logout = fopen(fname,"w");
  3132. +    }
  3133. +  
  3134. +  if (*lookup)
  3135. +    {
  3136. +      if (dbf)
  3137. +    fclose(dbf);
  3138. +      dbf = stdout;
  3139. +    }
  3140. +
  3141. +  DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  3142. +  DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
  3143. +
  3144. +  if (*host_file)
  3145. +    {
  3146. +      load_hosts_file(host_file);
  3147. +      DEBUG(3,("Loaded hosts file\n"));
  3148. +    }
  3149. +
  3150. +  init_structs();
  3151. +
  3152. +  if (*lookup) {
  3153. +    BOOL bcast = True;
  3154. +    int retries = 2;
  3155. +    char *p = strchr(lookup,'#');
  3156. +    struct in_addr ip;
  3157. +    if (p) {
  3158. +      *p = 0;
  3159. +      sscanf(p+1,"%x",&lookup_type);
  3160. +      bcast = False;
  3161. +      retries = 1;
  3162. +    }
  3163. +    if (!open_sockets(True,port)) return(1);
  3164. +    while (retries--)
  3165. +      if (name_query(lookup,lookup_type,bcast,True,bcast_ip,&ip)) {
  3166. +    printf("%s %s\n",inet_ntoa(ip),lookup);
  3167. +    name_status(lookup,lookup_type,ip,NULL);
  3168. +    return(0);
  3169. +      } 
  3170. +    printf("couldn't find name %s\n",lookup);
  3171. +    return(0);
  3172. +  }
  3173. +
  3174. +  if (!*comment)
  3175. +    strcpy(comment,"Samba %v");
  3176. +  string_sub(comment,"%v",VERSION);
  3177. +  string_sub(comment,"%h",myhostname);
  3178. +
  3179. +  check_names();
  3180. +
  3181. +  DEBUG(3,("Checked names\n"));
  3182. +  
  3183. +  dump_names();
  3184. +
  3185. +  DEBUG(3,("Dumped names\n"));
  3186. +
  3187. +  if (!is_daemon && !is_a_socket(0)) {
  3188. +    DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  3189. +    is_daemon = True;
  3190. +  }
  3191. +  
  3192. +
  3193. +  if (is_daemon) {
  3194. +    DEBUG(2,("%s becoming a daemon\n",timestring()));
  3195. +    become_daemon();
  3196. +  }
  3197. +
  3198. +
  3199. +  DEBUG(3,("Opening sockets\n"));
  3200. +
  3201. +  if (open_sockets(is_daemon,port))
  3202. +    {
  3203. +      process();
  3204. +      close_sockets();
  3205. +    }
  3206. +
  3207. +  if (dbf)
  3208. +    fclose(dbf);
  3209. +  return(0);
  3210. +}
  3211. diff -u -r --new-file last-version/source/nmblib.c samba-1.9.14p3/source/nmblib.c
  3212. --- last-version/source/nmblib.c    Thu Jan  1 10:00:00 1970
  3213. +++ samba-1.9.14p3/source/nmblib.c    Tue Nov  7 22:25:10 1995
  3214. @@ -0,0 +1,504 @@
  3215. +/* 
  3216. +   Unix SMB/Netbios implementation.
  3217. +   Version 1.9.
  3218. +   NBT netbios routines and daemon - version 2
  3219. +   Copyright (C) Andrew Tridgell 1994-1995
  3220. +   
  3221. +   This program is free software; you can redistribute it and/or modify
  3222. +   it under the terms of the GNU General Public License as published by
  3223. +   the Free Software Foundation; either version 2 of the License, or
  3224. +   (at your option) any later version.
  3225. +   
  3226. +   This program is distributed in the hope that it will be useful,
  3227. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  3228. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3229. +   GNU General Public License for more details.
  3230. +   
  3231. +   You should have received a copy of the GNU General Public License
  3232. +   along with this program; if not, write to the Free Software
  3233. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3234. +   
  3235. +*/
  3236. +
  3237. +#include "includes.h"
  3238. +#include "nameserv.h"
  3239. +
  3240. +extern int DEBUGLEVEL;
  3241. +
  3242. +int num_good_sends=0;
  3243. +int  num_good_receives=0;
  3244. +
  3245. +/*******************************************************************
  3246. +  handle "compressed" name pointers
  3247. +  ******************************************************************/
  3248. +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
  3249. +                 BOOL *got_pointer,int *ret)
  3250. +{
  3251. +  int loop_count=0;
  3252. +
  3253. +  while ((ubuf[*offset] & 0xC0) == 0xC0) {
  3254. +    if (!*got_pointer) (*ret) += 2;
  3255. +    (*got_pointer)=True;
  3256. +    (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
  3257. +    if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
  3258. +      return(False);
  3259. +    }
  3260. +  }
  3261. +  return(True);
  3262. +}
  3263. +
  3264. +/*******************************************************************
  3265. +  parse a nmb name from "compressed" format to something readable
  3266. +  return the space taken by the name, or 0 if the name is invalid
  3267. +  ******************************************************************/
  3268. +static int parse_nmb_name(char *inbuf,int offset,int length,
  3269. +              struct nmb_name *name)
  3270. +{
  3271. +  int m,n=0;
  3272. +  unsigned char *ubuf = (unsigned char *)inbuf;
  3273. +  int ret = 0;
  3274. +  BOOL got_pointer=False;
  3275. +
  3276. +  if (length - offset < 2) return(0);  
  3277. +
  3278. +  /* handle initial name pointers */
  3279. +  if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
  3280. +  
  3281. +  m = ubuf[offset];
  3282. +
  3283. +  if (!m) return(0);
  3284. +  if ((m & 0xC0) || offset+m+2 > length) return(0);
  3285. +
  3286. +  bzero((char *)name,sizeof(*name));
  3287. +
  3288. +  /* the "compressed" part */
  3289. +  if (!got_pointer) ret += m + 2;
  3290. +  offset++;
  3291. +  while (m) {
  3292. +    unsigned char c1,c2;
  3293. +    c1 = ubuf[offset++]-'A';
  3294. +    c2 = ubuf[offset++]-'A';
  3295. +    if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
  3296. +    name->name[n++] = (c1<<4) | c2;
  3297. +    m -= 2;
  3298. +  }
  3299. +  name->name[n] = 0;
  3300. +
  3301. +  if (n==16) {
  3302. +    /* parse out the name type, 
  3303. +       its always in the 16th byte of the name */
  3304. +    name->name_type = name->name[15];
  3305. +  
  3306. +    /* remove trailing spaces */
  3307. +    name->name[15] = 0;
  3308. +    n = 14;
  3309. +    while (n && name->name[n]==' ') name->name[n--] = 0;  
  3310. +  }
  3311. +
  3312. +  /* now the domain parts (if any) */
  3313. +  n = 0;
  3314. +  while ((m=ubuf[offset])) {
  3315. +    /* we can have pointers within the domain part as well */
  3316. +    if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
  3317. +
  3318. +    if (!got_pointer) ret += m+1;
  3319. +    if (n) name->scope[n++] = '.';
  3320. +    if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
  3321. +    offset++;
  3322. +    while (m--) name->scope[n++] = (char)ubuf[offset++];
  3323. +  }
  3324. +  name->scope[n++] = 0;  
  3325. +
  3326. +  return(ret);
  3327. +}
  3328. +
  3329. +
  3330. +/*******************************************************************
  3331. +  put a compressed nmb name into a buffer. return the length of the
  3332. +  compressed name
  3333. +  ******************************************************************/
  3334. +static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
  3335. +{
  3336. +  int ret,m;
  3337. +  char buf1[16];
  3338. +  char *p;
  3339. +
  3340. +  sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
  3341. +  buf[offset] = 0x20;
  3342. +
  3343. +  ret = 34;
  3344. +
  3345. +  for (m=0;m<16;m++) {
  3346. +    buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
  3347. +    buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
  3348. +  }
  3349. +  offset += 33;
  3350. +
  3351. +  buf[offset] = 0;
  3352. +
  3353. +  if (name->scope[0]) {
  3354. +    /* XXXX this scope handling needs testing */
  3355. +    ret += strlen(name->scope) + 1;
  3356. +    strcpy(&buf[offset+1],name->scope);  
  3357. +  
  3358. +    p = &buf[offset+1];
  3359. +    while ((p = strchr(p,'.'))) {
  3360. +      buf[offset] = PTR_DIFF(p,&buf[offset]);
  3361. +      offset += buf[offset];
  3362. +      p = &buf[offset+1];
  3363. +    }
  3364. +    buf[offset] = strlen(&buf[offset+1]);
  3365. +  }
  3366. +
  3367. +  return(ret);
  3368. +}
  3369. +
  3370. +
  3371. +/*******************************************************************
  3372. +  allocate are parse some resource records
  3373. +  ******************************************************************/
  3374. +static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
  3375. +                struct res_rec **recs,
  3376. +                int count)
  3377. +{
  3378. +  int i;
  3379. +  *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
  3380. +  if (!*recs) return(False);
  3381. +
  3382. +  bzero(*recs,sizeof(**recs)*count);
  3383. +
  3384. +  for (i=0;i<count;i++) {
  3385. +    int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
  3386. +    (*offset) += l;
  3387. +    if (!l || (*offset)+10 > length) {
  3388. +      free(*recs);
  3389. +      return(False);
  3390. +    }
  3391. +    (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
  3392. +    (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
  3393. +    (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
  3394. +    (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
  3395. +    (*offset) += 10;
  3396. +    if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
  3397. +    (*offset)+(*recs)[i].rdlength > length) {
  3398. +      free(*recs);
  3399. +      return(False);
  3400. +    }
  3401. +    memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
  3402. +    (*offset) += (*recs)[i].rdlength;    
  3403. +  }
  3404. +  return(True);
  3405. +}
  3406. +
  3407. +/*******************************************************************
  3408. +  put a resource record into a packet
  3409. +  ******************************************************************/
  3410. +static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
  3411. +{
  3412. +  int ret=0;
  3413. +  int i;
  3414. +
  3415. +  for (i=0;i<count;i++) {
  3416. +    int l = put_nmb_name(buf,offset,&recs[i].rr_name);
  3417. +    offset += l;
  3418. +    ret += l;
  3419. +    RSSVAL(buf,offset,recs[i].rr_type);
  3420. +    RSSVAL(buf,offset+2,recs[i].rr_class);
  3421. +    RSIVAL(buf,offset+4,recs[i].ttl);
  3422. +    RSSVAL(buf,offset+8,recs[i].rdlength);
  3423. +    memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
  3424. +    offset += 10+recs[i].rdlength;
  3425. +    ret += 10+recs[i].rdlength;
  3426. +  }
  3427. +
  3428. +  return(ret);
  3429. +}
  3430. +
  3431. +/*******************************************************************
  3432. +  parse a dgram packet. Return False if the packet can't be parsed 
  3433. +  or is invalid for some reason, True otherwise 
  3434. +  ******************************************************************/
  3435. +static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
  3436. +{
  3437. +  int offset;
  3438. +
  3439. +  bzero((char *)dgram,sizeof(*dgram));
  3440. +
  3441. +  if (length < 14) return(False);
  3442. +
  3443. +  dgram->header.res = RSVAL(inbuf,0);
  3444. +  dgram->header.id = RSVAL(inbuf,2);
  3445. +  putip((char *)&dgram->header.ip,inbuf+4);
  3446. +  dgram->header.port = RSVAL(inbuf,8);
  3447. +  dgram->header.length = RSVAL(inbuf,10);
  3448. +  dgram->header.res2 = RSVAL(inbuf,12);
  3449. +
  3450. +  offset = 14;
  3451. +  offset += parse_nmb_name(inbuf,offset,length,&dgram->header.source_name);
  3452. +  offset += parse_nmb_name(inbuf,offset,length,&dgram->header.dest_name);
  3453. +
  3454. +  if (offset >= length || (length-offset > sizeof(dgram->smb_data))) 
  3455. +    return(False);
  3456. +
  3457. +  dgram->smbsize = length-offset;
  3458. +  memcpy(dgram->smb_data,inbuf+offset,dgram->smbsize);
  3459. +
  3460. +  return(True);
  3461. +}
  3462. +
  3463. +
  3464. +/*******************************************************************
  3465. +  parse a nmb packet. Return False if the packet can't be parsed 
  3466. +  or is invalid for some reason, True otherwise 
  3467. +  ******************************************************************/
  3468. +static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
  3469. +{
  3470. +  int nm_flags,offset;
  3471. +
  3472. +  bzero((char *)nmb,sizeof(*nmb));
  3473. +
  3474. +  if (length < 12) return(False);
  3475. +
  3476. +  /* parse the header */
  3477. +  nmb->header.name_trn_id = RSVAL(inbuf,0);
  3478. +  nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
  3479. +  nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
  3480. +  nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
  3481. +  nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
  3482. +  nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
  3483. +  nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
  3484. +  nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
  3485. +  nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
  3486. +  nmb->header.rcode = CVAL(inbuf,3) & 0xF;
  3487. +  nmb->header.qdcount = RSVAL(inbuf,4);
  3488. +  nmb->header.ancount = RSVAL(inbuf,6);
  3489. +  nmb->header.nscount = RSVAL(inbuf,8);
  3490. +  nmb->header.arcount = RSVAL(inbuf,10);
  3491. +  
  3492. +  if (nmb->header.qdcount) {
  3493. +    offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
  3494. +    if (!offset) return(False);
  3495. +
  3496. +    if (length - (12+offset) < 4) return(False);
  3497. +    nmb->question.question_type = RSVAL(inbuf,12+offset);
  3498. +    nmb->question.question_class = RSVAL(inbuf,12+offset+2);
  3499. +
  3500. +    offset += 12+4;
  3501. +  } else {
  3502. +    offset = 12;
  3503. +  }
  3504. +
  3505. +  /* and any resource records */
  3506. +  if (nmb->header.ancount && 
  3507. +      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
  3508. +               nmb->header.ancount))
  3509. +    return(False);
  3510. +
  3511. +  if (nmb->header.nscount && 
  3512. +      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
  3513. +               nmb->header.nscount))
  3514. +    return(False);
  3515. +  
  3516. +  if (nmb->header.arcount && 
  3517. +      !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
  3518. +               nmb->header.arcount))
  3519. +    return(False);
  3520. +
  3521. +  return(True);
  3522. +}
  3523. +
  3524. +/*******************************************************************
  3525. +  free up any resources associated with an nmb packet
  3526. +  ******************************************************************/
  3527. +void free_nmb_packet(struct nmb_packet *nmb)
  3528. +{  
  3529. +  if (nmb->answers) free(nmb->answers);
  3530. +  if (nmb->nsrecs) free(nmb->nsrecs);
  3531. +  if (nmb->additional) free(nmb->additional);
  3532. +}
  3533. +
  3534. +/*******************************************************************
  3535. +  free up any resources associated with a packet
  3536. +  ******************************************************************/
  3537. +void free_packet(struct packet_struct *packet)
  3538. +{  
  3539. +  free_nmb_packet(&packet->packet.nmb);
  3540. +  free(packet);
  3541. +}
  3542. +
  3543. +/*******************************************************************
  3544. +  read a packet from a socket and parse it, returning a packet ready
  3545. +  to be used or put on the queue. This assumes a UDP socket
  3546. +  ******************************************************************/
  3547. +struct packet_struct *read_packet(int fd,enum packet_type packet_type)
  3548. +{
  3549. +  extern struct in_addr lastip;
  3550. +  extern int lastport;
  3551. +  struct packet_struct *packet;
  3552. +  char buf[MAX_DGRAM_SIZE];
  3553. +  int length;
  3554. +  BOOL ok=False;
  3555. +
  3556. +  length = read_udp_socket(fd,buf,sizeof(buf));
  3557. +  if (length < MIN_DGRAM_SIZE) return(NULL);
  3558. +
  3559. +  packet = (struct packet_struct *)malloc(sizeof(*packet));
  3560. +  if (!packet) return(NULL);
  3561. +
  3562. +  packet->next = NULL;
  3563. +  packet->prev = NULL;
  3564. +  packet->ip = lastip;
  3565. +  packet->port = lastport;
  3566. +  packet->fd = fd;
  3567. +  packet->timestamp = time(NULL);
  3568. +  packet->packet_type = packet_type;
  3569. +  switch (packet_type) 
  3570. +    {
  3571. +    case NMB_PACKET:
  3572. +      ok = parse_nmb(buf,length,&packet->packet.nmb);
  3573. +      break;
  3574. +
  3575. +    case DGRAM_PACKET:
  3576. +      ok = parse_dgram(buf,length,&packet->packet.dgram);
  3577. +      break;
  3578. +    }
  3579. +  if (!ok) {
  3580. +    free(packet);
  3581. +    return(NULL);
  3582. +  }
  3583. +
  3584. +  num_good_receives++;
  3585. +
  3586. +  return(packet);
  3587. +}
  3588. +                     
  3589. +
  3590. +/*******************************************************************
  3591. +  send a udp packet on a already open socket
  3592. +  ******************************************************************/
  3593. +static BOOL send_udp(int fd,char *buf,int len,struct in_addr *ip,int port)
  3594. +{
  3595. +  BOOL ret;
  3596. +  struct sockaddr_in sock_out;
  3597. +
  3598. +  /* set the address and port */
  3599. +  bzero((char *)&sock_out,sizeof(sock_out));
  3600. +  putip((char *)&sock_out.sin_addr,(char *)ip);
  3601. +  sock_out.sin_port = htons( port );
  3602. +  sock_out.sin_family = AF_INET;
  3603. +  
  3604. +  DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
  3605. +       len,inet_ntoa(*ip)));
  3606. +    
  3607. +  ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
  3608. +        sizeof(sock_out)) >= 0);
  3609. +
  3610. +  if (!ret)
  3611. +    DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
  3612. +
  3613. +  if (ret)
  3614. +    num_good_sends++;
  3615. +
  3616. +  return(ret);
  3617. +}
  3618. +
  3619. +
  3620. +/*******************************************************************
  3621. +  build a nmb packet ready for sending
  3622. +
  3623. +  XXXX this currently relies on not being passed something that expands
  3624. +  to a packet too big for the buffer. Eventually this should be
  3625. +  changed to set the trunc bit so the receiver can request the rest
  3626. +  via tcp (when that becomes supported)
  3627. +  ******************************************************************/
  3628. +static int build_nmb(char *buf,struct packet_struct *p)
  3629. +{
  3630. +  struct nmb_packet *nmb = &p->packet.nmb;
  3631. +  unsigned char *ubuf = (unsigned char *)buf;
  3632. +  int offset=0;
  3633. +
  3634. +  /* put in the header */
  3635. +  RSSVAL(ubuf,offset,nmb->header.name_trn_id);
  3636. +  ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
  3637. +  if (nmb->header.response) ubuf[offset+2] |= (1<<7);
  3638. +  if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
  3639. +  if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
  3640. +  if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
  3641. +  if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
  3642. +  if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
  3643. +  ubuf[offset+3] |= (nmb->header.rcode & 0xF);
  3644. +  RSSVAL(ubuf,offset+4,nmb->header.qdcount);
  3645. +  RSSVAL(ubuf,offset+6,nmb->header.ancount);
  3646. +  RSSVAL(ubuf,offset+8,nmb->header.nscount);
  3647. +  RSSVAL(ubuf,offset+10,nmb->header.arcount);
  3648. +  
  3649. +  offset += 12;
  3650. +  if (nmb->header.qdcount) {
  3651. +    /* XXXX this doesn't handle a qdcount of > 1 */
  3652. +    offset += put_nmb_name(ubuf,offset,&nmb->question.question_name);
  3653. +    RSSVAL(ubuf,offset,nmb->question.question_type);
  3654. +    RSSVAL(ubuf,offset+2,nmb->question.question_class);
  3655. +    offset += 4;
  3656. +  }
  3657. +
  3658. +  if (nmb->header.ancount)
  3659. +    offset += put_res_rec(ubuf,offset,nmb->answers,nmb->header.ancount);
  3660. +
  3661. +  if (nmb->header.nscount)
  3662. +    offset += put_res_rec(ubuf,offset,nmb->nsrecs,nmb->header.nscount);
  3663. +
  3664. +  if (nmb->header.arcount)
  3665. +    offset += put_res_rec(ubuf,offset,nmb->additional,nmb->header.arcount);  
  3666. +
  3667. +  return(offset);
  3668. +}
  3669. +
  3670. +
  3671. +/*******************************************************************
  3672. +  send a packet_struct
  3673. +  ******************************************************************/
  3674. +BOOL send_packet(struct packet_struct *p)
  3675. +{
  3676. +  char buf[1024];
  3677. +  int len=0;
  3678. +
  3679. +  bzero(buf,sizeof(buf));
  3680. +
  3681. +  switch (p->packet_type) 
  3682. +    {
  3683. +    case NMB_PACKET:
  3684. +      len = build_nmb(buf,p);
  3685. +      break;
  3686. +
  3687. +    case DGRAM_PACKET:
  3688. +      /* len = build_dgram(buf,p); */
  3689. +      break;
  3690. +    }
  3691. +
  3692. +  if (!len) return(False);
  3693. +
  3694. +  return(send_udp(p->fd,buf,len,&p->ip,p->port));
  3695. +}
  3696. +
  3697. +/****************************************************************************
  3698. +  receive a packet with timeout on a open UDP filedescriptor
  3699. +  The timeout is in milliseconds
  3700. +  ***************************************************************************/
  3701. +struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
  3702. +{
  3703. +  fd_set fds;
  3704. +  struct timeval timeout;
  3705. +
  3706. +  FD_ZERO(&fds);
  3707. +  FD_SET(fd,&fds);
  3708. +  timeout.tv_sec = t/1000;
  3709. +  timeout.tv_usec = 1000*(t%1000);
  3710. +
  3711. +  sys_select(&fds,&timeout);
  3712. +
  3713. +  if (FD_ISSET(fd,&fds)) 
  3714. +    return(read_packet(fd,type));
  3715. +
  3716. +  return(NULL);
  3717. +}
  3718. +
  3719. diff -u -r --new-file last-version/source/password.c samba-1.9.14p3/source/password.c
  3720. --- last-version/source/password.c    Fri Sep 22 10:37:06 1995
  3721. +++ samba-1.9.14p3/source/password.c    Sun Nov  5 15:51:20 1995
  3722. @@ -568,7 +568,7 @@
  3723.  /****************************************************************************
  3724.  check if a username/password is OK
  3725.  ****************************************************************************/
  3726. -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
  3727. +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password)
  3728.  {
  3729.    pstring pass2;
  3730.    int level = lp_passwordlevel();
  3731. @@ -641,6 +641,26 @@
  3732.        return(False);
  3733.      }
  3734.  
  3735. +    if(Protocol >= PROTOCOL_NT1 && is_nt_password)
  3736. +    {
  3737. +        /* We have the NT MD4 hash challenge available - see if we can
  3738. +           use it (ie. does it exist in the smbpasswd file).
  3739. +        */
  3740. +        if(smb_pass->smb_nt_passwd != NULL)
  3741. +        {
  3742. +          DEBUG(4,("Checking NT MD4 password\n"));
  3743. +          if(smb_password_check(password, smb_pass->smb_nt_passwd, challenge))
  3744. +             {
  3745. +              update_protected_database(user,True);
  3746. +            return(True);
  3747. +          }
  3748. +          DEBUG(4,("NT MD4 password check failed\n"));
  3749. +          return (False);
  3750. +        }
  3751. +    }
  3752. +
  3753. +    /* Try against the lanman password */
  3754. +
  3755.        if(smb_password_check(password, smb_pass->smb_passwd, challenge))
  3756.      {
  3757.        update_protected_database(user,True);
  3758. @@ -819,7 +839,7 @@
  3759.      while (getnetgrent(&host, &user, &domain)) {
  3760.        if (user) {
  3761.      if (user_ok(user, snum) && 
  3762. -        password_ok(user,password,pwlen,NULL)) {
  3763. +        password_ok(user,password,pwlen,NULL,False)) {
  3764.        endnetgrent();
  3765.        return(user);
  3766.      }
  3767. @@ -841,7 +861,7 @@
  3768.          static fstring name;
  3769.          strcpy(name,*member);
  3770.          if (user_ok(name,snum) &&
  3771. -        password_ok(name,password,pwlen,NULL))
  3772. +        password_ok(name,password,pwlen,NULL,False))
  3773.            return(&name[0]);
  3774.          member++;
  3775.        }
  3776. @@ -854,7 +874,7 @@
  3777.        while (pwd = getpwent ()) {
  3778.          if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
  3779.            /* This Entry have PASSWORD and same GID then check pwd */
  3780. -          if (password_ok(NULL, password, pwlen, pwd)) {
  3781. +          if (password_ok(NULL, password, pwlen, pwd,False)) {
  3782.          strcpy(tm, pwd->pw_name);
  3783.          endpwent ();
  3784.          return tm;
  3785. @@ -905,14 +925,14 @@
  3786.  
  3787.        /* check the given username and password */
  3788.        if (!ok && (*user) && user_ok(user,snum)) {
  3789. -    ok = password_ok(user,password, pwlen, NULL);
  3790. +    ok = password_ok(user,password, pwlen, NULL, False);
  3791.      if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
  3792.        }
  3793.  
  3794.        /* check for a previously registered guest username */
  3795.        if (!ok && (vuid >= 0) && validated_users[vuid].guest) {      
  3796.      if (user_ok(validated_users[vuid].name,snum) &&
  3797. -        password_ok(validated_users[vuid].name, password, pwlen, NULL)) {
  3798. +        password_ok(validated_users[vuid].name, password, pwlen, NULL, False)) {
  3799.        strcpy(user, validated_users[vuid].name);
  3800.        validated_users[vuid].guest = False;
  3801.        DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
  3802. @@ -936,7 +956,7 @@
  3803.            strcpy(user2,auser);
  3804.            if (!user_ok(user2,snum)) continue;
  3805.            
  3806. -          if (password_ok(user2,password, pwlen, NULL)) {
  3807. +          if (password_ok(user2,password, pwlen, NULL, False)) {
  3808.          ok = True;
  3809.          strcpy(user,user2);
  3810.          DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
  3811. @@ -988,7 +1008,7 @@
  3812.          fstring user2;
  3813.          strcpy(user2,auser);
  3814.          if (user_ok(user2,snum) && 
  3815. -            password_ok(user2,password,pwlen,NULL))
  3816. +            password_ok(user2,password,pwlen,NULL, False))
  3817.            {
  3818.              ok = True;
  3819.              strcpy(user,user2);
  3820. diff -u -r --new-file last-version/source/printing.c samba-1.9.14p3/source/printing.c
  3821. --- last-version/source/printing.c    Thu Nov  2 09:59:36 1995
  3822. +++ samba-1.9.14p3/source/printing.c    Mon Nov  6 16:53:58 1995
  3823. @@ -83,7 +83,7 @@
  3824.         the subshell causes a "cd" to be executed.
  3825.         Only use the full path if there isn't a / preceding the %s */
  3826.      if (iOffset==0 || syscmd[iOffset-1] != '/') {
  3827. -      StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename));
  3828. +      StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1);
  3829.        trim_string(filename,"","/");
  3830.        strcat(filename,"/");
  3831.        strcat(filename,filename1);
  3832. @@ -143,7 +143,10 @@
  3833.    lpq_reset(snum);
  3834.  }
  3835.  
  3836. +static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  3837. +                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
  3838.  
  3839. +
  3840.  /*******************************************************************
  3841.  process time fields
  3842.  ********************************************************************/
  3843. @@ -156,8 +159,6 @@
  3844.      struct tm *t;
  3845.      int i, day, hour, min, sec;
  3846.      char   *c;
  3847. -    const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  3848. -                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err" };
  3849.  
  3850.      for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
  3851.      if (i<12) {
  3852. @@ -186,7 +187,6 @@
  3853.        jobtime = mktime(t);
  3854.      }
  3855.    }
  3856. -  jobtime += GMT_TO_LOCAL*TimeDiff(jobtime);
  3857.    return jobtime;
  3858.  }
  3859.  
  3860. diff -u -r --new-file last-version/source/reply.c samba-1.9.14p3/source/reply.c
  3861. --- last-version/source/reply.c    Sat Nov  4 22:32:47 1995
  3862. +++ samba-1.9.14p3/source/reply.c    Mon Nov  6 16:14:59 1995
  3863. @@ -290,6 +290,9 @@
  3864.    uint32   smb_sesskey;    
  3865.    int   smb_apasslen;   
  3866.    pstring smb_apasswd;
  3867. +  int   smb_ntpasslen = 0;   
  3868. +  pstring smb_ntpasswd;
  3869. +  BOOL valid_nt_password = False;
  3870.    pstring user;
  3871.    BOOL guest=False;
  3872.  
  3873. @@ -316,10 +319,11 @@
  3874.      if (passlen2 > 256) passlen2 = 0; /* I don't know why NT gives weird 
  3875.                      lengths sometimes */
  3876.      if(doencrypt) {
  3877. -      /* Use the lanman2 password for now until the NT md4 password
  3878. -     is worked out. */
  3879. +      /* Save the lanman2 password and the NT md4 password. */
  3880.        smb_apasslen = passlen1;
  3881.        memcpy(smb_apasswd,p,smb_apasslen);
  3882. +      smb_ntpasslen = passlen2;
  3883. +      memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
  3884.      } else {
  3885.        /* for Win95 */
  3886.        if (passlen1 > passlen2) {
  3887. @@ -359,8 +363,17 @@
  3888.      guest = True;
  3889.    
  3890.        /* now check if it's a valid username/password */
  3891. -      if (!guest && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
  3892. +    /* If an NT password was supplied try and validate with that
  3893. +       first. This is superior as the passwords are mixed case 128 length unicode */
  3894. +    if(smb_ntpasslen && !guest)
  3895.      {
  3896. +        if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL,True))
  3897. +            DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
  3898. +        else
  3899. +            valid_nt_password = True;
  3900. +    } 
  3901. +    if (!valid_nt_password && !guest && !password_ok(user,smb_apasswd,smb_apasslen,NULL,False))
  3902. +    {
  3903.  #if !GUEST_SESSSETUP
  3904.        if (lp_security() >= SEC_USER)
  3905.          return(ERROR(ERRSRV,ERRbadpw));
  3906. @@ -456,7 +469,7 @@
  3907.    mode = SVAL(inbuf,smb_vwv0);
  3908.  
  3909.    if (check_name(name,cnum))
  3910. -    ok = directory_exist(name);
  3911. +    ok = directory_exist(name,NULL);
  3912.  
  3913.    if (!ok)
  3914.      return(ERROR(ERRDOS,ERRbadpath));
  3915. @@ -520,7 +533,7 @@
  3916.    outsize = set_message(outbuf,10,0,True);
  3917.  
  3918.    SSVAL(outbuf,smb_vwv0,mode);
  3919. -  SIVAL(outbuf,smb_vwv1,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
  3920. +  put_dos_date3(outbuf,smb_vwv1,mtime);
  3921.    SIVAL(outbuf,smb_vwv3,size);
  3922.  
  3923.    if (Protocol >= PROTOCOL_NT1) {
  3924. @@ -555,14 +568,14 @@
  3925.    unix_convert(fname,cnum);
  3926.  
  3927.    mode = SVAL(inbuf,smb_vwv0);
  3928. -  mtime = IVAL(inbuf,smb_vwv1);
  3929. +  mtime = make_unix_date3(inbuf+smb_vwv1);
  3930.    
  3931. -  if (directory_exist(fname))
  3932. +  if (directory_exist(fname,NULL))
  3933.      mode |= aDIR;
  3934.    if (check_name(fname,cnum))
  3935.      ok =  (dos_chmod(cnum,fname,mode) == 0);
  3936. -  if (ok && mtime != 0)
  3937. -    ok = set_filetime(fname,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
  3938. +  if (ok)
  3939. +    ok = set_filetime(fname,mtime);
  3940.    
  3941.    if (!ok)
  3942.      return(UNIXERROR(ERRDOS,ERRnoaccess));
  3943. @@ -930,7 +943,7 @@
  3944.    outsize = set_message(outbuf,7,0,True);
  3945.    SSVAL(outbuf,smb_vwv0,fnum);
  3946.    SSVAL(outbuf,smb_vwv1,fmode);
  3947. -  SIVAL(outbuf,smb_vwv2,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
  3948. +  put_dos_date3(outbuf,smb_vwv2,mtime);
  3949.    SIVAL(outbuf,smb_vwv4,size);
  3950.    SSVAL(outbuf,smb_vwv6,rmode);
  3951.      
  3952. @@ -955,7 +968,7 @@
  3953.  #if 0
  3954.    int open_flags = SVAL(inbuf,smb_vwv2);
  3955.    int smb_sattr = SVAL(inbuf,smb_vwv4); 
  3956. -  uint32 smb_time = IVAL(inbuf,smb_vwv6);
  3957. +  uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
  3958.  #endif
  3959.    int smb_ofun = SVAL(inbuf,smb_vwv8);
  3960.    int unixmode;
  3961. @@ -1007,7 +1020,7 @@
  3962.    SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
  3963.    SSVAL(outbuf,smb_vwv2,fnum);
  3964.    SSVAL(outbuf,smb_vwv3,fmode);
  3965. -  SIVAL(outbuf,smb_vwv4,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
  3966. +  put_dos_date3(outbuf,smb_vwv4,mtime);
  3967.    SIVAL(outbuf,smb_vwv6,size);
  3968.    SSVAL(outbuf,smb_vwv8,rmode);
  3969.    SSVAL(outbuf,smb_vwv11,smb_action);
  3970. @@ -1918,15 +1931,12 @@
  3971.      err = Files[fnum].wbmpx_ptr->wr_error;
  3972.    }
  3973.  
  3974. -  mtime = IVAL(inbuf,smb_vwv1);
  3975. +  mtime = make_unix_date3(inbuf+smb_vwv1);
  3976.  
  3977.    close_file(fnum);
  3978.  
  3979.    /* try and set the date */
  3980. -  if (mtime == 0 || mtime == -1)
  3981. -    DEBUG(5,("not setting null date\n"));
  3982. -  else
  3983. -    set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
  3984. +  set_filetime(Files[fnum].name,mtime);
  3985.  
  3986.    /* We have a cached error */
  3987.    if(eclass || err)
  3988. @@ -1961,7 +1971,7 @@
  3989.  
  3990.    numtowrite = SVAL(inbuf,smb_vwv1);
  3991.    startpos = IVAL(inbuf,smb_vwv2);
  3992. -  mtime = IVAL(inbuf,smb_vwv4);
  3993. +  mtime = make_unix_date3(inbuf+smb_vwv4);
  3994.    data = smb_buf(inbuf) + 1;
  3995.    
  3996.    if (is_locked(fnum,cnum,numtowrite,startpos))
  3997. @@ -1973,10 +1983,7 @@
  3998.  
  3999.    close_file(fnum);
  4000.  
  4001. -  if (mtime == 0 || mtime == -1)
  4002. -    DEBUG(5,("not setting null date\n"));
  4003. -  else
  4004. -    set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
  4005. +  set_filetime(Files[fnum].name,mtime);
  4006.    
  4007.    DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
  4008.         timestring(),fnum,cnum,numtowrite,nwritten,
  4009. @@ -2516,6 +2523,7 @@
  4010.      strcat(directory,mask);
  4011.      if (resolve_wildcards(directory,newname) && 
  4012.      can_rename(directory,cnum) && 
  4013. +    !file_exist(newname,NULL) &&
  4014.      !sys_rename(directory,newname)) count++;
  4015.      if (!count) exists = file_exist(directory,NULL);
  4016.    } else {
  4017. @@ -2545,6 +2553,7 @@
  4018.          if (!can_rename(fname,cnum)) continue;
  4019.          strcpy(destname,newname);
  4020.          if (resolve_wildcards(fname,destname) && 
  4021. +        !file_exist(destname,NULL) && 
  4022.          !sys_rename(fname,destname)) count++;
  4023.          DEBUG(3,("reply_mv : doing rename on %s -> %s\n",fname,destname));
  4024.        }
  4025. @@ -2588,7 +2597,7 @@
  4026.      ok = True;
  4027.    else
  4028.      {
  4029. -      ok = directory_exist(newdir);
  4030. +      ok = directory_exist(newdir,NULL);
  4031.        if (ok)
  4032.      string_set(&Connections[cnum].connectpath,newdir);
  4033.      }
  4034. @@ -2943,12 +2952,8 @@
  4035.    /* Convert the DOS times into unix times. Ignore create
  4036.       time as UNIX can't set this.
  4037.       */
  4038. -  
  4039. -  /* XXXX - should this include the DST offset? */
  4040. -  unix_times.actime = make_unix_date2(inbuf+smb_vwv3,False);
  4041. -  unix_times.modtime = make_unix_date2(inbuf+smb_vwv5,False);
  4042. -  unix_times.actime += LOCAL_TO_GMT*TimeDiff(unix_times.actime);
  4043. -  unix_times.modtime += LOCAL_TO_GMT*TimeDiff(unix_times.modtime);
  4044. +  unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
  4045. +  unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
  4046.    
  4047.    /* Set the date on this file */
  4048.    if(sys_utime(Files[fnum].name, &unix_times))
  4049. diff -u -r --new-file last-version/source/server.c samba-1.9.14p3/source/server.c
  4050. --- last-version/source/server.c    Sat Nov  4 22:11:05 1995
  4051. +++ samba-1.9.14p3/source/server.c    Tue Nov  7 18:24:54 1995
  4052. @@ -347,7 +347,8 @@
  4053.        (strequal(dname,".") || strequal(dname,"..")))
  4054.      continue;
  4055.  
  4056. -      if (!name_convert(name2,dname,False,snum)) continue;
  4057. +      strcpy(name2,dname);
  4058. +      if (!name_map_mangle(name2,False,snum)) continue;
  4059.  
  4060.        if ((mangled && mangled_equal(name,name2))
  4061.        || fname_equal(name, name2))
  4062. @@ -1709,8 +1710,7 @@
  4063.  ****************************************************************************/
  4064.  BOOL unbecome_user(void )
  4065.  {
  4066. -  if (ChDir(OriginalDir) != 0)
  4067. -    DEBUG(0,("%s chdir(%s) failed\n",timestring(),OriginalDir));  
  4068. +  ChDir(OriginalDir);
  4069.  
  4070.    if (done_become_user == -1)
  4071.      return(False);
  4072. @@ -1747,7 +1747,8 @@
  4073.  #endif
  4074.    
  4075.    if (ChDir(OriginalDir) != 0)
  4076. -    DEBUG(0,("%s chdir(%s) failed\n",timestring(),OriginalDir));  
  4077. +    DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
  4078. +         timestring(),OriginalDir));  
  4079.  
  4080.    DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
  4081.      getuid(),geteuid(),getgid(),getegid()));
  4082. @@ -3143,7 +3144,7 @@
  4083.    standard_sub(cnum,fname);
  4084.    trim_string(fname,"","/");
  4085.  
  4086. -  if (!directory_exist(fname))
  4087. +  if (!directory_exist(fname,NULL))
  4088.      mkdir(fname,0755);
  4089.  
  4090.    strcat(fname,"/");
  4091. @@ -3208,10 +3209,8 @@
  4092.    crec.uid = Connections[cnum].uid;
  4093.    crec.gid = Connections[cnum].gid;
  4094.    StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
  4095. -  {
  4096. -    time_t t = time(NULL);
  4097. -    crec.start = t + GMT_TO_LOCAL*TimeDiff(t);
  4098. -  }
  4099. +  crec.start = time(NULL);
  4100. +
  4101.    {
  4102.      extern struct from_host Client_info;
  4103.      StrnCpy(crec.machine,Client_info.name,sizeof(crec.machine)-1);
  4104. @@ -3744,7 +3743,7 @@
  4105.      uint32 a = interpret_addr("localhost");
  4106.      putip((void *)&ip,(void *)&a);
  4107.      *OutBuffer = 0;
  4108. -    send_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
  4109. +    send_one_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
  4110.    }
  4111.  #endif    
  4112.    
  4113. @@ -3963,6 +3962,8 @@
  4114.  #ifdef OSF1_ENH_SEC
  4115.    set_auth_parameters(argc,argv);
  4116.  #endif
  4117. +
  4118. +  TimeInit();
  4119.  
  4120.    charset_initialise();
  4121.  
  4122. diff -u -r --new-file last-version/source/smb.h samba-1.9.14p3/source/smb.h
  4123. --- last-version/source/smb.h    Sat Nov  4 22:13:27 1995
  4124. +++ samba-1.9.14p3/source/smb.h    Tue Nov  7 18:24:53 1995
  4125. @@ -210,6 +210,7 @@
  4126.    int mode;
  4127.    int uid;
  4128.    int gid;
  4129. +  /* these times are normally kept in GMT */
  4130.    time_t mtime;
  4131.    time_t atime;
  4132.    time_t ctime;
  4133. @@ -695,7 +696,7 @@
  4134.  void add_session_user(char *user);
  4135.  int valid_uid(int uid);
  4136.  user_struct *get_valid_user_struct(int uid);
  4137. -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
  4138. +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL nt_password);
  4139.  void register_uid(int uid,int gid,char *name,BOOL guest);
  4140.  BOOL fromhost(int sock,struct from_host *f);
  4141.  BOOL strhasupper(char *s);
  4142. @@ -707,7 +708,7 @@
  4143.  BOOL check_file_sharing(int cnum,char *fname);
  4144.  char *StrCpy(char *dest,char *src);
  4145.  int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
  4146. -time_t make_unix_date2(void *date_ptr,BOOL add_dst);
  4147. +time_t make_unix_date2(void *date_ptr);
  4148.  int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
  4149.  mode_t unix_mode(int cnum,int dosmode);
  4150.  BOOL check_name(char *name,int cnum);
  4151. @@ -724,7 +725,7 @@
  4152.  BOOL yield_connection(int cnum,char *name,int max_connections);
  4153.  int count_chars(char *s,char c);
  4154.  int smbrun(char *,char *);
  4155. -BOOL name_convert(char *OutName,char *InName,BOOL need83,int snum);
  4156. +BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
  4157.  struct hostent *Get_Hostbyname(char *name);
  4158.  struct passwd *Get_Pwnam(char *user,BOOL allow_change);
  4159.  void Abort(void);
  4160. @@ -738,7 +739,9 @@
  4161.  void string_free(char **s);
  4162.  char *attrib_string(int mode);
  4163.  void unix_format(char *fname);
  4164. -BOOL directory_exist(char *dname);
  4165. +BOOL directory_exist(char *dname,struct stat *st);
  4166. +time_t make_unix_date3(void *date_ptr);
  4167. +void put_dos_date3(char *buf,int offset,time_t unixdate);
  4168.  void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
  4169.  BOOL in_list(char *s,char *list,BOOL case_sensitive);
  4170.  void strupper(char *s);
  4171. @@ -767,7 +770,7 @@
  4172.  int dos_mode(int ,char *,struct stat *);
  4173.  char *timestring();
  4174.  BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
  4175. -BOOL send_packet(char *buf,int len,struct in_addr *ip,int port,int type);
  4176. +BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type);
  4177.  char *get_home_dir(char *);
  4178.  int set_filelen(int fd, long len);
  4179.  void put_dos_date(char *buf,int offset,time_t unixdate);
  4180. @@ -776,7 +779,7 @@
  4181.  int name_len(char *s);
  4182.  void dos_clean_name(char *s);
  4183.  void unix_clean_name(char *s);
  4184. -time_t make_unix_date(void *date_ptr,BOOL add_dst);
  4185. +time_t make_unix_date(void *date_ptr);
  4186.  BOOL lanman2_match( char *str, char *regexp, int case_sig, BOOL autoext);
  4187.  BOOL trim_string(char *s,char *front,char *back);
  4188.  int byte_checksum(char *buf,int len);
  4189. diff -u -r --new-file last-version/source/smbencrypt.c samba-1.9.14p3/source/smbencrypt.c
  4190. --- last-version/source/smbencrypt.c    Tue Jul 11 21:56:15 1995
  4191. +++ samba-1.9.14p3/source/smbencrypt.c    Sun Nov  5 15:46:54 1995
  4192. @@ -24,12 +24,24 @@
  4193.  #include "includes.h"
  4194.  #include "loadparm.h"
  4195.  #include "des.h"
  4196. +#include "md4.h"
  4197.  
  4198.  extern int DEBUGLEVEL;
  4199.  
  4200.  #ifndef uchar
  4201.  #define uchar unsigned char
  4202.  #endif
  4203. +#ifndef int16
  4204. +#define int16 unsigned short
  4205. +#endif
  4206. +#ifndef uint16
  4207. +#define uint16 unsigned short
  4208. +#endif
  4209. +#ifndef uint32
  4210. +#define uint32 unsigned int
  4211. +#endif
  4212. +
  4213. +#include "byteorder.h"
  4214.  
  4215.  void str_to_key(uchar *str,uchar *key)
  4216.  {
  4217. @@ -110,6 +122,81 @@
  4218.    E_P16(p14, p21);
  4219.    E_P24(p21, c8, p24);
  4220.  }
  4221. +
  4222. +/* Routines for Windows NT MD4 Hash functions. */
  4223. +static int _my_wcslen(int16 *str)
  4224. +{
  4225. +    int len = 0;
  4226. +    while(*str++ != 0)
  4227. +        len++;
  4228. +    return len;
  4229. +}
  4230. +
  4231. +/*
  4232. + * Convert a string into an NT UNICODE string.
  4233. + * Note that regardless of processor type 
  4234. + * this must be in intel (little-endian)
  4235. + * format.
  4236. + */
  4237. +static int _my_mbstowcs(int16 *dst, uchar *src, int len)
  4238. +{
  4239. +    int i;
  4240. +    int16 val;
  4241. +    for(i = 0; i < len; i++) {
  4242. +        val = *src;
  4243. +        SSVAL(dst,0,val);
  4244. +        dst++;
  4245. +        src++;
  4246. +        if(val == 0)
  4247. +            break;
  4248. +    }
  4249. +    return i;
  4250. +}
  4251. +
  4252. +/* 
  4253. + * Creates the MD4 Hash of the users password in NT UNICODE.
  4254. + */
  4255. +void E_md4hash(uchar *passwd, uchar *p16)
  4256. +{
  4257. +    int i, len;
  4258. +    int16 wpwd[129];
  4259. +    MDstruct MD;
  4260. +    /* Password cannot be longer than 128 characters */
  4261. +    len = strlen(passwd);
  4262. +    if(len > 128)
  4263. +        len = 128;
  4264. +    /* Password must be converted to NT unicode */
  4265. +    _my_mbstowcs( wpwd, passwd, len);
  4266. +    wpwd[len] = 0; /* Ensure string is null terminated */
  4267. +    /* Calculate length in bytes */
  4268. +    len = _my_wcslen(wpwd) * sizeof(int16);
  4269. +    MDbegin(&MD);
  4270. +    for(i = 0; i + 64 <= len; i += 64)
  4271. +        MDupdate(&MD,wpwd + (i/2), 512);
  4272. +    MDupdate(&MD,wpwd + (i/2),(len-i)*8);
  4273. +    SIVAL(p16,0,MD.buffer[0]);
  4274. +    SIVAL(p16,4,MD.buffer[1]);
  4275. +    SIVAL(p16,8,MD.buffer[2]);
  4276. +    SIVAL(p16,12,MD.buffer[3]);
  4277. +}
  4278. +
  4279. +/* Does the NT MD4 hash then des encryption. */
  4280. +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
  4281. +{
  4282. +    uchar p21[21];
  4283. +    memset(p21,'\0',21);
  4284. +    E_md4hash(passwd, p21);    
  4285. +    E_P24(p21, c8, p24);
  4286. +}
  4287. +
  4288.  #else
  4289.  void smbencrypt_dummy(void){}
  4290.  #endif
  4291. diff -u -r --new-file last-version/source/smbpass.c samba-1.9.14p3/source/smbpass.c
  4292. --- last-version/source/smbpass.c    Sun Sep 10 23:10:41 1995
  4293. +++ samba-1.9.14p3/source/smbpass.c    Mon Nov  6 16:54:57 1995
  4294. @@ -1,281 +1,304 @@
  4295.  #ifdef SMB_PASSWD
  4296. -/* 
  4297. -   Unix SMB/Netbios implementation.
  4298. -   Version 1.9.
  4299. -   SMB parameters and setup
  4300. -   Copyright (C) Andrew Tridgell 1992-1995
  4301. -   Modified by Jeremy Allison 1995.
  4302. -   
  4303. -   This program is free software; you can redistribute it and/or modify
  4304. -   it under the terms of the GNU General Public License as published by
  4305. -   the Free Software Foundation; either version 2 of the License, or
  4306. -   (at your option) any later version.
  4307. -   
  4308. -   This program is distributed in the hope that it will be useful,
  4309. -   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4310. -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4311. -   GNU General Public License for more details.
  4312. -   
  4313. -   You should have received a copy of the GNU General Public License
  4314. -   along with this program; if not, write to the Free Software
  4315. -   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4316. -*/
  4317. +/*
  4318. + * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
  4319. + * Copyright (C) Andrew Tridgell 1992-1995 Modified by Jeremy Allison 1995.
  4320. + * 
  4321. + * This program is free software; you can redistribute it and/or modify it under
  4322. + * the terms of the GNU General Public License as published by the Free
  4323. + * Software Foundation; either version 2 of the License, or (at your option)
  4324. + * any later version.
  4325. + * 
  4326. + * This program is distributed in the hope that it will be useful, but WITHOUT
  4327. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4328. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  4329. + * more details.
  4330. + * 
  4331. + * You should have received a copy of the GNU General Public License along with
  4332. + * this program; if not, write to the Free Software Foundation, Inc., 675
  4333. + * Mass Ave, Cambridge, MA 02139, USA.
  4334. + */
  4335.  
  4336.  #include "includes.h"
  4337.  #include "loadparm.h"
  4338.  
  4339. -extern int DEBUGLEVEL;
  4340. +extern int      DEBUGLEVEL;
  4341.  
  4342. -int gotalarm;
  4343. +int             gotalarm;
  4344.  
  4345. -void gotalarm_sig()
  4346. +void 
  4347. +gotalarm_sig()
  4348.  {
  4349. -    gotalarm = 1;
  4350. +    gotalarm = 1;
  4351.  }
  4352.  
  4353. -int do_pw_lock(int fd, int waitsecs, int type)
  4354. +int 
  4355. +do_pw_lock(int fd, int waitsecs, int type)
  4356.  {
  4357. -    struct flock lock;
  4358. -    int ret;
  4359. +    struct flock    lock;
  4360. +    int             ret;
  4361.  
  4362. -    gotalarm = 0;
  4363. +    gotalarm = 0;
  4364.      signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
  4365.  
  4366. -    lock.l_type = type;
  4367. -    lock.l_whence = SEEK_SET;
  4368. -    lock.l_start = 0;
  4369. -    lock.l_len = 1;
  4370. -    lock.l_pid = 0;
  4371. -
  4372. -    alarm(5);
  4373. -    ret = fcntl(fd, F_SETLKW, &lock);
  4374. -    alarm(0);
  4375. -    signal( SIGALRM, SIGNAL_CAST SIG_DFL);
  4376. -
  4377. -    if(gotalarm) {
  4378. -        DEBUG(0,("do_pw_lock: failed to %s SMB passwd file.\n",
  4379. -        type == F_UNLCK ? "unlock" : "lock" ));
  4380. -        return -1;
  4381. -    }
  4382. -    return ret;
  4383. +    lock.l_type = type;
  4384. +    lock.l_whence = SEEK_SET;
  4385. +    lock.l_start = 0;
  4386. +    lock.l_len = 1;
  4387. +    lock.l_pid = 0;
  4388. +
  4389. +    alarm(5);
  4390. +    ret = fcntl(fd, F_SETLKW, &lock);
  4391. +    alarm(0);
  4392. +    signal(SIGALRM, SIGNAL_CAST SIG_DFL);
  4393. +
  4394. +    if (gotalarm) {
  4395. +        DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
  4396. +              type == F_UNLCK ? "unlock" : "lock"));
  4397. +        return -1;
  4398. +    }
  4399. +    return ret;
  4400.  }
  4401.  
  4402. -int pw_file_lock(const char *name, int type, int secs)
  4403. +int 
  4404. +pw_file_lock(char *name, int type, int secs)
  4405.  {
  4406. -    int fd = open(name,O_RDWR|O_CREAT,0666);
  4407. -    if (fd < 0) return(-1);
  4408. -    if(do_pw_lock(fd, secs, type))
  4409. -      {
  4410. +    int             fd = open(name, O_RDWR | O_CREAT, 0666);
  4411. +    if (fd < 0)
  4412. +        return (-1);
  4413. +    if (do_pw_lock(fd, secs, type)) {
  4414.          close(fd);
  4415.          return -1;
  4416. -      }
  4417. +    }
  4418.      return fd;
  4419.  }
  4420.  
  4421. -int pw_file_unlock(int fd)
  4422. +int 
  4423. +pw_file_unlock(int fd)
  4424.  {
  4425.      do_pw_lock(fd, 5, F_UNLCK);
  4426.      return close(fd);
  4427.  }
  4428.  
  4429.  /*
  4430. - * Routine to search the smbpasswd file for an
  4431. - * entry matching the username.
  4432. + * Routine to get the next 32 hex characters and turn them
  4433. + * into a 16 byte array.
  4434.   */
  4435. -struct smb_passwd *get_smbpwnam(char *name)
  4436. +
  4437. +static int gethexpwd(char *p, char *pwd)
  4438.  {
  4439. -  /* Static buffers we will return. */
  4440. -  static struct smb_passwd pw_buf;
  4441. -  static pstring user_name;
  4442. -  static unsigned char smbpwd[16];
  4443. -  char linebuf[256];
  4444. -  char readbuf[16*1024];
  4445. -  unsigned char c;
  4446. -  unsigned char *p;
  4447. -  long uidval;
  4448. -  long linebuf_len;
  4449. -  unsigned char lonybble, hinybble;
  4450. -  int i;
  4451. -  FILE *fp;
  4452. -  int lockfd;
  4453. -  char *pfile = lp_smb_passwd_file();
  4454. -
  4455. -  if (!*pfile) {
  4456. -    DEBUG(0,("No SMB password file set\n"));
  4457. -    return(NULL);
  4458. -  }
  4459. -
  4460. -  DEBUG(10,("get_smbpwnam: opening file %s\n", pfile));
  4461. -  
  4462. -  fp = fopen(pfile,"r");
  4463. -  
  4464. -  if(fp == NULL) 
  4465. -    {
  4466. -      DEBUG(0,("get_smbpwnam: unable to open file %s\n", pfile));
  4467. -      return NULL;
  4468. -    }
  4469. -
  4470. -  /* Set a 16k buffer to do more efficient reads */  
  4471. -  setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  4472. -
  4473. -  if((lockfd = pw_file_lock(pfile,F_RDLCK,5))<0) {
  4474. -    DEBUG(0,("get_smbpwnam: unable to lock file %s\n", pfile));
  4475. -    fclose(fp);
  4476. -    return NULL;
  4477. -  }
  4478. -
  4479. -  /* make sure it is only rw by the owner */
  4480. -  chmod(pfile,0600);
  4481. -  
  4482. -  /* We have a read lock on the file. */
  4483. -  /* Scan the file, a line at a time and
  4484. -     check if the name matches. */
  4485. -  while(!feof(fp)) 
  4486. -    {
  4487. -      linebuf[0] = '\0';
  4488. -
  4489. -      fgets(linebuf, 256, fp);
  4490. -      if(ferror(fp))
  4491. -    {
  4492. -      fclose(fp);
  4493. -      pw_file_unlock(lockfd);
  4494. -      return NULL;
  4495. +    int i;
  4496. +    unsigned char   lonybble, hinybble;
  4497. +    char           *hexchars = "0123456789ABCDEF";
  4498. +    char           *p1, *p2;
  4499. +
  4500. +    for (i = 0; i < 32; i += 2) {
  4501. +        hinybble = toupper(p[i]);
  4502. +        lonybble = toupper(p[i + 1]);
  4503. +        p1 = strchr(hexchars, hinybble);
  4504. +        p2 = strchr(hexchars, lonybble);
  4505. +        if (!p1 || !p2)
  4506. +            return (False);
  4507. +        hinybble = PTR_DIFF(p1, hexchars);
  4508. +        lonybble = PTR_DIFF(p2, hexchars);
  4509. +        pwd[i / 2] = (hinybble << 4) | lonybble;
  4510.      }
  4511. +    return (True);
  4512. +}
  4513.  
  4514. -      /* Check if the string is terminated with a newline -
  4515. -     if not then we must keep reading and discard until
  4516. -     we get one.
  4517. -     */
  4518. -      linebuf_len = strlen(linebuf);
  4519. -      if(linebuf[linebuf_len-1] != '\n')
  4520. -    {
  4521. -      c = '\0';
  4522. -      while(!ferror(fp) && !feof(fp))
  4523. -        {
  4524. -          c = fgetc(fp);
  4525. -          if(c == '\n')
  4526. -        break;
  4527. -        }
  4528. +/*
  4529. + * Routine to search the smbpasswd file for an entry matching the username.
  4530. + */
  4531. +struct smb_passwd *
  4532. +get_smbpwnam(char *name)
  4533. +{
  4534. +    /* Static buffers we will return. */
  4535. +    static struct smb_passwd pw_buf;
  4536. +    static pstring  user_name;
  4537. +    static unsigned char smbpwd[16];
  4538. +    static unsigned char smbntpwd[16];
  4539. +    char            linebuf[256];
  4540. +    char            readbuf[16 * 1024];
  4541. +    unsigned char   c;
  4542. +    unsigned char  *p;
  4543. +    long            uidval;
  4544. +    long            linebuf_len;
  4545. +    FILE           *fp;
  4546. +    int             lockfd;
  4547. +    char           *pfile = lp_smb_passwd_file();
  4548. +
  4549. +    if (!*pfile) {
  4550. +        DEBUG(0, ("No SMB password file set\n"));
  4551. +        return (NULL);
  4552.      }
  4553. -      else
  4554. -    linebuf[linebuf_len-1] = '\0';
  4555. +    DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile));
  4556.  
  4557. -#ifdef DEBUG_PASSWORD
  4558. -      DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
  4559. -#endif
  4560. -      if((linebuf[0] == 0) && feof(fp))
  4561. -    {
  4562. -      DEBUG(4,("get_smbpwnam: end of file reached\n"));
  4563. -      break;
  4564. -    }
  4565. -      /* The line we have should be of the form :-
  4566. -     
  4567. -     username:uid:[32hex bytes]:....other flags presently ignored....
  4568. -     
  4569. -     */
  4570. +    fp = fopen(pfile, "r");
  4571.  
  4572. -      if(linebuf[0] == '#' || linebuf[0] == '\0')
  4573. -    {
  4574. -      DEBUG(6,("get_smbpwnam: skipping comment or blank line\n"));
  4575. -      continue;
  4576. -    }
  4577. -      p = (unsigned char *)strchr(linebuf, ':');
  4578. -      if( p == NULL)
  4579. -    {
  4580. -      DEBUG(0,("get_smbpwnam: malformed password entry (no :)\n"));
  4581. -      continue;
  4582. +    if (fp == NULL) {
  4583. +        DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile));
  4584. +        return NULL;
  4585.      }
  4586. -      /* As 256 is shorter than a pstring we don't
  4587. -     need to check length here - if this ever changes.... */
  4588. -      strncpy(user_name, linebuf, PTR_DIFF(p,linebuf));
  4589. -      user_name[PTR_DIFF(p,linebuf)] = '\0';
  4590. -      if(!strequal(user_name, name))
  4591. -    continue;
  4592. -
  4593. -      /* User name matches - get uid and password */
  4594. -      p++;            /* Go past ':' */
  4595. -      if(!isdigit(*p)) {
  4596. -    DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
  4597. -    fclose(fp);
  4598. -    pw_file_unlock(lockfd);
  4599. -    return NULL;
  4600. -      }
  4601. +    /* Set a 16k buffer to do more efficient reads */
  4602. +    setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  4603.  
  4604. -      uidval = atoi((char *)p);
  4605. -      while (*p && isdigit(*p)) p++;
  4606. -      if(*p != ':') {
  4607. -    DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
  4608. -    fclose(fp);
  4609. -    pw_file_unlock(lockfd);
  4610. -    return NULL;
  4611. -      }
  4612. +    if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
  4613. +        DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile));
  4614. +        fclose(fp);
  4615. +        return NULL;
  4616. +    }
  4617. +    /* make sure it is only rw by the owner */
  4618. +    chmod(pfile, 0600);
  4619.  
  4620. -      /* Now get the password value - this should be 32 hex digits which
  4621. -     are the ascii representations of a 16 byte string. Get two at
  4622. -     a time and put them into the password.
  4623. +    /* We have a read lock on the file. */
  4624. +    /*
  4625. +     * Scan the file, a line at a time and check if the name matches.
  4626.       */
  4627. -      p++;
  4628. -      if(*p == '*' || *p == 'X') {
  4629. -    /* Password deliberately invalid - end here. */
  4630. -    DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
  4631. -    fclose(fp);
  4632. -    pw_file_unlock(lockfd);
  4633. -    return NULL;
  4634. -      }
  4635. -      if(linebuf_len < (PTR_DIFF(p,linebuf) + 33)) {
  4636. -    DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
  4637. -    fclose(fp);
  4638. -    pw_file_unlock(lockfd);
  4639. -    return(False);
  4640. -      }
  4641. +    while (!feof(fp)) {
  4642. +        linebuf[0] = '\0';
  4643. +
  4644. +        fgets(linebuf, 256, fp);
  4645. +        if (ferror(fp)) {
  4646. +            fclose(fp);
  4647. +            pw_file_unlock(lockfd);
  4648. +            return NULL;
  4649. +        }
  4650. +        /*
  4651. +         * Check if the string is terminated with a newline - if not
  4652. +         * then we must keep reading and discard until we get one.
  4653. +         */
  4654. +        linebuf_len = strlen(linebuf);
  4655. +        if (linebuf[linebuf_len - 1] != '\n') {
  4656. +            c = '\0';
  4657. +            while (!ferror(fp) && !feof(fp)) {
  4658. +                c = fgetc(fp);
  4659. +                if (c == '\n')
  4660. +                    break;
  4661. +            }
  4662. +        } else
  4663. +            linebuf[linebuf_len - 1] = '\0';
  4664. +
  4665. +#ifdef DEBUG_PASSWORD
  4666. +        DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
  4667. +#endif
  4668. +        if ((linebuf[0] == 0) && feof(fp)) {
  4669. +            DEBUG(4, ("get_smbpwnam: end of file reached\n"));
  4670. +            break;
  4671. +        }
  4672. +        /*
  4673. +         * The line we have should be of the form :-
  4674. +         * 
  4675. +         * username:uid:[32hex bytes]:....other flags presently
  4676. +         * ignored....
  4677. +         * 
  4678. +         * or,
  4679. +         *
  4680. +         * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
  4681. +         *
  4682. +         * if Windows NT compatible passwords are also present.
  4683. +         */
  4684. +
  4685. +        if (linebuf[0] == '#' || linebuf[0] == '\0') {
  4686. +            DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n"));
  4687. +            continue;
  4688. +        }
  4689. +        p = (unsigned char *) strchr(linebuf, ':');
  4690. +        if (p == NULL) {
  4691. +            DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n"));
  4692. +            continue;
  4693. +        }
  4694. +        /*
  4695. +         * As 256 is shorter than a pstring we don't need to check
  4696. +         * length here - if this ever changes....
  4697. +         */
  4698. +        strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
  4699. +        user_name[PTR_DIFF(p, linebuf)] = '\0';
  4700. +        if (!strequal(user_name, name))
  4701. +            continue;
  4702. +
  4703. +        /* User name matches - get uid and password */
  4704. +        p++;        /* Go past ':' */
  4705. +        if (!isdigit(*p)) {
  4706. +            DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n"));
  4707. +            fclose(fp);
  4708. +            pw_file_unlock(lockfd);
  4709. +            return NULL;
  4710. +        }
  4711. +        uidval = atoi((char *) p);
  4712. +        while (*p && isdigit(*p))
  4713. +            p++;
  4714. +        if (*p != ':') {
  4715. +            DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n"));
  4716. +            fclose(fp);
  4717. +            pw_file_unlock(lockfd);
  4718. +            return NULL;
  4719. +        }
  4720. +        /*
  4721. +         * Now get the password value - this should be 32 hex digits
  4722. +         * which are the ascii representations of a 16 byte string.
  4723. +         * Get two at a time and put them into the password.
  4724. +         */
  4725. +        p++;
  4726. +        if (*p == '*' || *p == 'X') {
  4727. +            /* Password deliberately invalid - end here. */
  4728. +            DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name));
  4729. +            fclose(fp);
  4730. +            pw_file_unlock(lockfd);
  4731. +            return NULL;
  4732. +        }
  4733. +        if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
  4734. +            DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n"));
  4735. +            fclose(fp);
  4736. +            pw_file_unlock(lockfd);
  4737. +            return (False);
  4738. +        }
  4739. +        if (p[32] != ':') {
  4740. +            DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n"));
  4741. +            fclose(fp);
  4742. +            pw_file_unlock(lockfd);
  4743. +            return NULL;
  4744. +        }
  4745. +        if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
  4746. +            pw_buf.smb_passwd = NULL;
  4747. +        } else {
  4748. +            if(!gethexpwd(p,smbpwd)) {
  4749. +                DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
  4750. +                fclose(fp);
  4751. +                pw_file_unlock(lockfd);
  4752. +                return NULL;
  4753. +            }
  4754. +            pw_buf.smb_passwd = smbpwd;
  4755. +        }
  4756. +        pw_buf.smb_name = user_name;
  4757. +        pw_buf.smb_userid = uidval;
  4758. +        pw_buf.smb_nt_passwd = NULL;
  4759. +
  4760. +        /* Now check if the NT compatible password is
  4761. +            available. */
  4762. +        p += 33; /* Move to the first character of the line after
  4763. +                    the lanman password. */
  4764. +        if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
  4765. +            if (*p != '*' && *p != 'X') {
  4766. +                if(gethexpwd(p,smbntpwd))
  4767. +                    pw_buf.smb_nt_passwd = smbntpwd;
  4768. +            }
  4769. +        }
  4770. +
  4771. +        fclose(fp);
  4772. +        pw_file_unlock(lockfd);
  4773. +        DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
  4774. +              user_name, uidval));
  4775. +        return &pw_buf;
  4776. +    }
  4777.  
  4778. -      if(p[32] != ':') {
  4779. -    DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
  4780.      fclose(fp);
  4781.      pw_file_unlock(lockfd);
  4782.      return NULL;
  4783. -      }
  4784. -
  4785. -      if (!strncasecmp((char *)p,"NO PASSWORD", 11)) {
  4786. -    pw_buf.smb_passwd = NULL;
  4787. -      } else {    
  4788. -    char *hexchars = "0123456789ABCDEF";
  4789. -    char *p1,*p2;
  4790. -    for(i = 0; i < 32; i += 2)
  4791. -      {
  4792. -        hinybble = toupper(p[i]);
  4793. -        lonybble = toupper(p[i+1]);
  4794. -        
  4795. -        p1 = strchr(hexchars,hinybble);
  4796. -        p2 = strchr(hexchars,lonybble);
  4797. -        if (!p1 || !p2) {
  4798. -          DEBUG(0,("Malformed password entry (non hex chars)\n"));
  4799. -          fclose(fp);
  4800. -          pw_file_unlock(lockfd);
  4801. -          return NULL;
  4802. -        }
  4803. -
  4804. -        hinybble = PTR_DIFF(p1,hexchars);
  4805. -        lonybble = PTR_DIFF(p2,hexchars);
  4806. -
  4807. -        smbpwd[i/2] = (hinybble << 4) | lonybble;
  4808. -      }
  4809. -    pw_buf.smb_passwd = smbpwd;
  4810. -      }
  4811. -      pw_buf.smb_name = user_name;
  4812. -      pw_buf.smb_userid = uidval;
  4813. -      fclose(fp);
  4814. -      pw_file_unlock(lockfd);
  4815. -      DEBUG(5,("get_smbpwname: returning passwd entry for user %s, uid %d\n",
  4816. -        user_name, uidval));
  4817. -      return &pw_buf;
  4818. -    }
  4819. -  
  4820. -  fclose(fp);
  4821. -  pw_file_unlock(lockfd);
  4822. -  return NULL;
  4823.  }
  4824.  #else
  4825. -void smbpass_dummy(void){} /* To avoid compiler complaints */
  4826. +void 
  4827. +smbpass_dummy(void)
  4828. +{
  4829. +}                /* To avoid compiler complaints */
  4830.  #endif
  4831. -
  4832. diff -u -r --new-file last-version/source/smbpass.h samba-1.9.14p3/source/smbpass.h
  4833. --- last-version/source/smbpass.h    Sun Sep 10 23:10:47 1995
  4834. +++ samba-1.9.14p3/source/smbpass.h    Mon Nov  6 16:54:56 1995
  4835. @@ -25,6 +25,7 @@
  4836.      int smb_userid;
  4837.      char *smb_name;
  4838.      unsigned char *smb_passwd; /* Null if no password */
  4839. +    unsigned char *smb_nt_passwd; /* Null if no password */
  4840.      /* Other fields / flags may be added later */
  4841.  };
  4842.  
  4843. @@ -39,9 +40,11 @@
  4844.  void str_to_key(unsigned char *str,unsigned char *key);
  4845.  void E_P16(uchar *p14,uchar *p16);
  4846.  void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
  4847. +void E_md4hash(uchar *passwd,uchar *p16);
  4848.  void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
  4849. +void SMB_nt_encrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
  4850.  
  4851.  /* Password file lock/unlock routines */
  4852. -int pw_file_lock(const char *name, int type, int secs);
  4853. +int pw_file_lock(char *name, int type, int secs);
  4854.  int pw_file_unlock(int fd);
  4855.  #endif
  4856. diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14p3/source/smbpasswd.c
  4857. --- last-version/source/smbpasswd.c    Sun Sep 10 23:28:28 1995
  4858. +++ samba-1.9.14p3/source/smbpasswd.c    Mon Nov  6 16:54:38 1995
  4859. @@ -1,381 +1,447 @@
  4860.  #ifdef SMB_PASSWD
  4861.  
  4862. -/* 
  4863. -   Unix SMB/Netbios implementation.
  4864. -   Version 1.9.
  4865. -   smbpasswd module.
  4866. -   Copyright (C) Jeremy Allison 1995.
  4867. -
  4868. -   This program is free software; you can redistribute it and/or modify
  4869. -   it under the terms of the GNU General Public License as published by
  4870. -   the Free Software Foundation; either version 2 of the License, or
  4871. -   (at your option) any later version.
  4872. -   
  4873. -   This program is distributed in the hope that it will be useful,
  4874. -   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4875. -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4876. -   GNU General Public License for more details.
  4877. -   
  4878. -   You should have received a copy of the GNU General Public License
  4879. -   along with this program; if not, write to the Free Software
  4880. -   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4881. -*/
  4882. +/*
  4883. + * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
  4884. + * (C) Jeremy Allison 1995.
  4885. + * 
  4886. + * This program is free software; you can redistribute it and/or modify it under
  4887. + * the terms of the GNU General Public License as published by the Free
  4888. + * Software Foundation; either version 2 of the License, or (at your option)
  4889. + * any later version.
  4890. + * 
  4891. + * This program is distributed in the hope that it will be useful, but WITHOUT
  4892. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4893. + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  4894. + * more details.
  4895. + * 
  4896. + * You should have received a copy of the GNU General Public License along with
  4897. + * this program; if not, write to the Free Software Foundation, Inc., 675
  4898. + * Mass Ave, Cambridge, MA 02139, USA.
  4899. + */
  4900.  
  4901.  #include "includes.h"
  4902.  #include "des.h"
  4903.  
  4904.  #ifdef SMBGETPASS
  4905. -extern char *getsmbpass(const char *);
  4906. +extern char    *getsmbpass(char *);
  4907.  #define getpass getsmbpass
  4908.  #endif
  4909.  
  4910.  /* Static buffers we will return. */
  4911.  static struct smb_passwd pw_buf;
  4912. -static pstring user_name;
  4913. +static pstring  user_name;
  4914.  static unsigned char smbpwd[16];
  4915. +static unsigned char smbntpwd[16];
  4916.  
  4917. -struct smb_passwd *_my_get_smbpwnam(FILE *fp,char *name, BOOL *valid_old_pwd, long *pwd_seekpos)
  4918. +static int gethexpwd(char *p, char *pwd)
  4919.  {
  4920. -  char linebuf[256];
  4921. -  unsigned char c;
  4922. -  unsigned char *p;
  4923. -  long uidval;
  4924. -  long linebuf_len;
  4925. -  unsigned char lonybble, hinybble;
  4926. -  int i;
  4927. -
  4928. -  /* Scan the file, a line at a time and
  4929. -     check if the name matches. */
  4930. -  while(!feof(fp)) 
  4931. -    {
  4932. -      linebuf[0] = '\0';
  4933. -      *pwd_seekpos = ftell(fp);
  4934. +    int i;
  4935. +    unsigned char   lonybble, hinybble;
  4936. +    char           *hexchars = "0123456789ABCDEF";
  4937. +    char           *p1, *p2;
  4938. +    for (i = 0; i < 32; i += 2) {
  4939. +        hinybble = toupper(p[i]);
  4940. +        lonybble = toupper(p[i + 1]);
  4941. +
  4942. +        p1 = strchr(hexchars, hinybble);
  4943. +        p2 = strchr(hexchars, lonybble);
  4944. +        if (!p1 || !p2)
  4945. +            return (False);
  4946.  
  4947. -      fgets(linebuf, 256, fp);
  4948. -      if(ferror(fp))
  4949. -    return NULL;
  4950. +        hinybble = PTR_DIFF(p1, hexchars);
  4951. +        lonybble = PTR_DIFF(p2, hexchars);
  4952.  
  4953. -      /* Check if the string is terminated with a newline -
  4954. -     if not then we must keep reading and discard until
  4955. -     we get one.
  4956. -     */
  4957. -      linebuf_len = strlen(linebuf);
  4958. -      if(linebuf[linebuf_len-1] != '\n')
  4959. -    {
  4960. -      c = '\0';
  4961. -      while(!ferror(fp) && !feof(fp))
  4962. -        {
  4963. -          c = fgetc(fp);
  4964. -          if(c == '\n')
  4965. -        break;
  4966. -        }
  4967. -    }
  4968. -      else
  4969. -    linebuf[linebuf_len-1] = '\0';
  4970. -
  4971. -      if((linebuf[0] == 0) && feof(fp))
  4972. -    break;
  4973. -      /* The line we have should be of the form :-
  4974. +        pwd[i / 2] = (hinybble << 4) | lonybble;
  4975. +    }
  4976. +    return (True);
  4977. +}
  4978.  
  4979. -     username:uid:[32hex bytes]:....other flags presently ignored....
  4980. -     */
  4981. +struct smb_passwd *
  4982. +_my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd, 
  4983. +        BOOL *got_valid_nt_entry, long *pwd_seekpos)
  4984. +{
  4985. +    char            linebuf[256];
  4986. +    unsigned char   c;
  4987. +    unsigned char  *p;
  4988. +    long            uidval;
  4989. +    long            linebuf_len;
  4990.  
  4991. -      if(linebuf[0] == '#' || linebuf[0] == '\0')
  4992. -    continue;
  4993. -      p = (unsigned char *)strchr(linebuf, ':');
  4994. -      if( p == NULL)
  4995. -    continue;
  4996. -      /* As 256 is shorter than a pstring we don't
  4997. -     need to check length here - if this ever changes.... */
  4998. -      strncpy( user_name, linebuf, PTR_DIFF(p,linebuf));
  4999. -      user_name[PTR_DIFF(p,linebuf)] = '\0';
  5000. -      if(!strequal(user_name, name))
  5001. -    continue;
  5002. -
  5003. -      /* User name matches - get uid and password */
  5004. -      p++; /* Go past ':' */
  5005. -      if(!isdigit(*p))
  5006. -    return(False);
  5007. -      
  5008. -      uidval = atoi((char *)p);
  5009. -      while (*p && isdigit(*p)) p++;
  5010. -
  5011. -      if(*p != ':')
  5012. -    return(False);
  5013. -      
  5014. -      /* Now get the password value - this should be 32 hex digits which
  5015. -     are the ascii representations of a 16 byte string. Get two at
  5016. -     a time and put them into the password.
  5017. +    /*
  5018. +     * Scan the file, a line at a time and check if the name matches.
  5019.       */
  5020. -      p++;
  5021. -      *pwd_seekpos += PTR_DIFF(p,linebuf); /* Save exact position of
  5022. -                          passwd in file - this is used
  5023. -                          by smbpasswd.c 
  5024. -                          */
  5025. -      if(*p == '*' || *p == 'X')
  5026. -    {
  5027. -      /* Password deliberately invalid - end here. */
  5028. -      *valid_old_pwd = False;
  5029. -      pw_buf.smb_name = user_name;
  5030. -      pw_buf.smb_userid = uidval;
  5031. -      return(&pw_buf);
  5032. -    }
  5033. -      if(linebuf_len < (PTR_DIFF(p,linebuf) + 33))
  5034. -    return(False);
  5035. -      
  5036. -      if(p[32] != ':')
  5037. -    return(False);
  5038. -
  5039. -      if(!strncasecmp(p,"NO PASSWORD",11)) {
  5040. -    pw_buf.smb_passwd = NULL; /* No password */
  5041. -      } else {
  5042. -    char *hexchars = "0123456789ABCDEF";
  5043. -    char *p1,*p2;    
  5044. -    for(i = 0; i < 32; i += 2)
  5045. -      {
  5046. -        hinybble = toupper(p[i]);
  5047. -        lonybble = toupper(p[i+1]);
  5048. -        
  5049. -        p1 = strchr(hexchars,hinybble);
  5050. -        p2 = strchr(hexchars,lonybble);
  5051. -        if (!p1 || !p2)
  5052. -          return(False);
  5053. -
  5054. -        hinybble = PTR_DIFF(p1,hexchars);
  5055. -        lonybble = PTR_DIFF(p2,hexchars);
  5056. -
  5057. -        smbpwd[i/2] = (hinybble << 4) | lonybble;
  5058. -      }
  5059. -    pw_buf.smb_passwd = smbpwd;
  5060. -      }
  5061. -      
  5062. -      pw_buf.smb_name = user_name;
  5063. -      pw_buf.smb_userid = uidval;
  5064. -      *valid_old_pwd = True;
  5065. -      return &pw_buf;
  5066. -    }
  5067. -  return NULL;
  5068. +    while (!feof(fp)) {
  5069. +        linebuf[0] = '\0';
  5070. +        *pwd_seekpos = ftell(fp);
  5071. +
  5072. +        fgets(linebuf, 256, fp);
  5073. +        if (ferror(fp))
  5074. +            return NULL;
  5075. +
  5076. +        /*
  5077. +         * Check if the string is terminated with a newline - if not
  5078. +         * then we must keep reading and discard until we get one.
  5079. +         */
  5080. +        linebuf_len = strlen(linebuf);
  5081. +        if (linebuf[linebuf_len - 1] != '\n') {
  5082. +            c = '\0';
  5083. +            while (!ferror(fp) && !feof(fp)) {
  5084. +                c = fgetc(fp);
  5085. +                if (c == '\n')
  5086. +                    break;
  5087. +            }
  5088. +        } else
  5089. +            linebuf[linebuf_len - 1] = '\0';
  5090. +
  5091. +        if ((linebuf[0] == 0) && feof(fp))
  5092. +            break;
  5093. +        /*
  5094. +         * The line we have should be of the form :-
  5095. +         * 
  5096. +         * username:uid:[32hex bytes]:....other flags presently
  5097. +         * ignored....
  5098. +         * 
  5099. +         * or,
  5100. +         * 
  5101. +         * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
  5102. +         * 
  5103. +         * if Windows NT compatible passwords are also present.
  5104. +         */
  5105. +
  5106. +        if (linebuf[0] == '#' || linebuf[0] == '\0')
  5107. +            continue;
  5108. +        p = (unsigned char *) strchr(linebuf, ':');
  5109. +        if (p == NULL)
  5110. +            continue;
  5111. +        /*
  5112. +         * As 256 is shorter than a pstring we don't need to check
  5113. +         * length here - if this ever changes....
  5114. +         */
  5115. +        strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
  5116. +        user_name[PTR_DIFF(p, linebuf)] = '\0';
  5117. +        if (!strequal(user_name, name))
  5118. +            continue;
  5119. +
  5120. +        /* User name matches - get uid and password */
  5121. +        p++;        /* Go past ':' */
  5122. +        if (!isdigit(*p))
  5123. +            return (False);
  5124. +
  5125. +        uidval = atoi((char *) p);
  5126. +        while (*p && isdigit(*p))
  5127. +            p++;
  5128. +
  5129. +        if (*p != ':')
  5130. +            return (False);
  5131. +
  5132. +        /*
  5133. +         * Now get the password value - this should be 32 hex digits
  5134. +         * which are the ascii representations of a 16 byte string.
  5135. +         * Get two at a time and put them into the password.
  5136. +         */
  5137. +        p++;
  5138. +        *pwd_seekpos += PTR_DIFF(p, linebuf);    /* Save exact position
  5139. +                             * of passwd in file -
  5140. +                             * this is used by
  5141. +                             * smbpasswd.c */
  5142. +        if (*p == '*' || *p == 'X') {
  5143. +            /* Password deliberately invalid - end here. */
  5144. +            *valid_old_pwd = False;
  5145. +            *got_valid_nt_entry = False;
  5146. +            pw_buf.smb_name = user_name;
  5147. +            pw_buf.smb_userid = uidval;
  5148. +            pw_buf.smb_passwd = NULL;    /* No password */
  5149. +            pw_buf.smb_nt_passwd = NULL;    /* No password */
  5150. +            return (&pw_buf);
  5151. +        }
  5152. +        if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
  5153. +            return (False);
  5154. +
  5155. +        if (p[32] != ':')
  5156. +            return (False);
  5157. +
  5158. +        if (!strncasecmp(p, "NO PASSWORD", 11)) {
  5159. +            pw_buf.smb_passwd = NULL;    /* No password */
  5160. +        } else {
  5161. +            if(!gethexpwd(p,smbpwd))
  5162. +                return False;
  5163. +            pw_buf.smb_passwd = smbpwd;
  5164. +        }
  5165. +
  5166. +        pw_buf.smb_name = user_name;
  5167. +        pw_buf.smb_userid = uidval;
  5168. +        pw_buf.smb_nt_passwd = NULL;
  5169. +        *got_valid_nt_entry = False;
  5170. +        *valid_old_pwd = True;
  5171. +
  5172. +        /* Now check if the NT compatible password is
  5173. +           available. */
  5174. +        p += 33; /* Move to the first character of the line after 
  5175. +                    the lanman password. */
  5176. +        if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
  5177. +            /* NT Entry was valid - even if 'X' or '*', can be overwritten */
  5178. +            *got_valid_nt_entry = True;
  5179. +            if (*p != '*' && *p != 'X') {
  5180. +                if(gethexpwd(p,smbntpwd))
  5181. +                    pw_buf.smb_nt_passwd = smbntpwd;
  5182. +            }
  5183. +        }
  5184. +        return &pw_buf;
  5185. +    }
  5186. +    return NULL;
  5187.  }
  5188.  
  5189.  /*
  5190.   * Print command usage on stderr and die.
  5191.   */
  5192. -void usage(char *name)
  5193. +void 
  5194. +usage(char *name)
  5195.  {
  5196.      fprintf(stderr, "Usage is : %s [username]\n", name);
  5197.      exit(1);
  5198.  }
  5199.  
  5200. -int main(int argc, char **argv)
  5201. +int 
  5202. +main(int argc, char **argv)
  5203.  {
  5204. -  int real_uid;
  5205. -  struct passwd *pwd;
  5206. -  fstring old_passwd;
  5207. -  uchar old_p16[16];
  5208. -  fstring new_passwd;
  5209. -  uchar new_p16[16];
  5210. -  char *p;
  5211. -  struct smb_passwd *smb_pwent;
  5212. -  FILE *fp;
  5213. -  BOOL valid_old_pwd = False;
  5214. -  long seekpos;
  5215. -  int pwfd;
  5216. -  char ascii_p16[33];
  5217. -  char c;
  5218. -  int ret, i, err;
  5219. -  int lockfd=-1;
  5220. -  char *pfile = SMB_PASSWD_FILE;
  5221. -  char readbuf[16*1024];
  5222. +    int             real_uid;
  5223. +    struct passwd  *pwd;
  5224. +    fstring         old_passwd;
  5225. +    uchar           old_p16[16];
  5226. +    uchar           old_nt_p16[16];
  5227. +    fstring         new_passwd;
  5228. +    uchar           new_p16[16];
  5229. +    uchar           new_nt_p16[16];
  5230. +    char           *p;
  5231. +    struct smb_passwd *smb_pwent;
  5232. +    FILE           *fp;
  5233. +    BOOL            valid_old_pwd = False;
  5234. +    BOOL             got_valid_nt_entry = False;
  5235. +    long            seekpos;
  5236. +    int             pwfd;
  5237. +    char            ascii_p16[66];
  5238. +    char            c;
  5239. +    int             ret, i, err, writelen;
  5240. +    int             lockfd = -1;
  5241. +    char           *pfile = SMB_PASSWD_FILE;
  5242. +    char            readbuf[16 * 1024];
  5243.  
  5244. -  charset_initialise();
  5245. +    charset_initialise();
  5246.  
  5247.  #ifndef DEBUG_PASSWORD
  5248. -  /* Check the effective uid */
  5249. -  if(geteuid() != 0) {
  5250. -    fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
  5251. -    exit(1);
  5252. -  }
  5253. +    /* Check the effective uid */
  5254. +    if (geteuid() != 0) {
  5255. +        fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
  5256. +        exit(1);
  5257. +    }
  5258.  #endif
  5259.  
  5260. -  /* Get the real uid */
  5261. -  real_uid = getuid();
  5262. -  
  5263. -  /* Deal with usage problems */
  5264. -  if( real_uid == 0) {
  5265. -    /* As root we can change anothers password. */
  5266. -    if(argc != 1 && argc != 2)
  5267. -      usage(argv[0]);
  5268. -  } else if(argc != 1)
  5269. -    usage(argv[0]);
  5270. -        
  5271. -
  5272. -  if(real_uid == 0 && argc == 2) {
  5273. -    /* If we are root we can change anothers password. */
  5274. -    strncpy( user_name, argv[1], sizeof(user_name)-1);
  5275. -    user_name[sizeof(user_name)-1] = '\0';
  5276. -    pwd = getpwnam( user_name );
  5277. -  } else {
  5278. -    pwd = getpwuid( real_uid );
  5279. -  }
  5280. -
  5281. -  if(pwd == 0) {
  5282. -    fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
  5283. -    exit(1);
  5284. -  }
  5285. -  
  5286. -  /* If we are root we don't ask for the old password. */
  5287. -  old_passwd[0] = '\0';
  5288. -  if(real_uid != 0) {
  5289. -    p = getpass("Old SMB password:");
  5290. -    strncpy(old_passwd, p, 14);
  5291. -    old_passwd[14] = '\0';
  5292. -    strupper(old_passwd);
  5293. -  }
  5294. -  
  5295. -  new_passwd[0] = '\0';
  5296. -  p = getpass("New SMB password:");
  5297. -  strncpy(new_passwd, p, 14);
  5298. -  new_passwd[14] = '\0';
  5299. -  p = getpass("Retype new SMB password:");
  5300. -  if(strncmp(p, new_passwd, 14)) {
  5301. -    fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
  5302. -    exit(1);
  5303. -  }
  5304. -  strupper(new_passwd);
  5305. -  
  5306. -  if(new_passwd[0] == '\0') {
  5307. -    printf("Password not set\n");
  5308. -    exit(0);
  5309. -  }
  5310. -  
  5311. -  /* Calculate the SMB hash functions of
  5312. -     both old an new passwords. */
  5313. -  
  5314. -  memset(old_p16,'\0',16);
  5315. -  E_P16((uchar *)old_passwd,old_p16);
  5316. -  
  5317. -  memset(new_p16,'\0',16);
  5318. -  E_P16((uchar *)new_passwd,new_p16);
  5319. -  
  5320. -  /* Open the smbpaswd file XXXX - we need to parse smb.conf to
  5321. -     get the filename */
  5322. -  if((fp = fopen(pfile, "r+")) == NULL) {
  5323. -    err = errno;
  5324. -    fprintf(stderr, "%s: Failed to open password file %s.\n", 
  5325. -        argv[0], pfile);
  5326. -    errno = err;
  5327. -    perror(argv[0]);
  5328. -    exit(err);
  5329. -  }
  5330. -
  5331. -  /* Set read buffer to 16k for effiecient reads */ 
  5332. -  setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  5333. -  /* make sure it is only rw by the owner */
  5334. -  chmod(pfile,0600);
  5335. -  
  5336. -  /* Lock the smbpasswd file for write. */
  5337. -  if((lockfd=pw_file_lock(pfile,F_WRLCK,5))<0) {
  5338. -    err = errno;
  5339. -    fprintf(stderr, "%s: Failed to lock password file %s.\n", 
  5340. -        argv[0], pfile);
  5341. -    fclose(fp);
  5342. -    errno = err;
  5343. -    perror(argv[0]);
  5344. -    exit(err);
  5345. -  }
  5346. -
  5347. -  /* Get the smb passwd entry for this user */
  5348. -  smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd, &seekpos);
  5349. -  if(smb_pwent == NULL) {
  5350. -    fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
  5351. -        argv[0], pwd->pw_name, pfile);
  5352. -    fclose(fp);
  5353. -    pw_file_unlock(lockfd);
  5354. -    exit(1);
  5355. -  }
  5356. -  
  5357. -  /* If we are root we don't need to check the old password. */
  5358. -  if( real_uid != 0) {
  5359. -    if( valid_old_pwd == False) {
  5360. -      fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
  5361. -      fclose(fp);
  5362. -      pw_file_unlock(lockfd);
  5363. -      exit(1);
  5364. +    /* Get the real uid */
  5365. +    real_uid = getuid();
  5366. +
  5367. +    /* Deal with usage problems */
  5368. +    if (real_uid == 0) {
  5369. +        /* As root we can change anothers password. */
  5370. +        if (argc != 1 && argc != 2)
  5371. +            usage(argv[0]);
  5372. +    } else if (argc != 1)
  5373. +        usage(argv[0]);
  5374. +
  5375. +
  5376. +    if (real_uid == 0 && argc == 2) {
  5377. +        /* If we are root we can change anothers password. */
  5378. +        strncpy(user_name, argv[1], sizeof(user_name) - 1);
  5379. +        user_name[sizeof(user_name) - 1] = '\0';
  5380. +        pwd = getpwnam(user_name);
  5381. +    } else {
  5382. +        pwd = getpwuid(real_uid);
  5383. +    }
  5384. +
  5385. +    if (pwd == 0) {
  5386. +        fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
  5387. +        exit(1);
  5388. +    }
  5389. +    /* If we are root we don't ask for the old password. */
  5390. +    old_passwd[0] = '\0';
  5391. +    if (real_uid != 0) {
  5392. +        p = getpass("Old SMB password:");
  5393. +        strncpy(old_passwd, p, sizeof(fstring));
  5394. +        old_passwd[sizeof(fstring)-1] = '\0';
  5395. +    }
  5396. +    new_passwd[0] = '\0';
  5397. +    p = getpass("New SMB password:");
  5398. +    strncpy(new_passwd, p, sizeof(fstring));
  5399. +    new_passwd[sizeof(fstring)-1] = '\0';
  5400. +    p = getpass("Retype new SMB password:");
  5401. +    if (strcmp(p, new_passwd)) {
  5402. +        fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
  5403. +        exit(1);
  5404. +    }
  5405. +
  5406. +    if (new_passwd[0] == '\0') {
  5407. +        printf("Password not set\n");
  5408. +        exit(0);
  5409. +    }
  5410. +
  5411. +    /* Calculate the MD4 hash (NT compatible) of the old and new passwords */
  5412. +    memset(old_nt_p16, '\0', 16);
  5413. +    E_md4hash((uchar *)old_passwd, old_nt_p16);
  5414. +
  5415. +    memset(new_nt_p16, '\0', 16);
  5416. +    E_md4hash((uchar *) new_passwd, new_nt_p16);
  5417. +
  5418. +    /* Mangle the passwords into Lanman format */
  5419. +    old_passwd[14] = '\0';
  5420. +    strupper(old_passwd);
  5421. +    new_passwd[14] = '\0';
  5422. +    strupper(new_passwd);
  5423. +
  5424. +    /*
  5425. +     * Calculate the SMB (lanman) hash functions of both old and new passwords.
  5426. +     */
  5427. +
  5428. +    memset(old_p16, '\0', 16);
  5429. +    E_P16((uchar *) old_passwd, old_p16);
  5430. +
  5431. +    memset(new_p16, '\0', 16);
  5432. +    E_P16((uchar *) new_passwd, new_p16);
  5433. +
  5434. +    /*
  5435. +     * Open the smbpaswd file XXXX - we need to parse smb.conf to get the
  5436. +     * filename
  5437. +     */
  5438. +    if ((fp = fopen(pfile, "r+")) == NULL) {
  5439. +        err = errno;
  5440. +        fprintf(stderr, "%s: Failed to open password file %s.\n",
  5441. +            argv[0], pfile);
  5442. +        errno = err;
  5443. +        perror(argv[0]);
  5444. +        exit(err);
  5445. +    }
  5446. +    /* Set read buffer to 16k for effiecient reads */
  5447. +    setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
  5448. +
  5449. +    /* make sure it is only rw by the owner */
  5450. +    chmod(pfile, 0600);
  5451. +
  5452. +    /* Lock the smbpasswd file for write. */
  5453. +    if ((lockfd = pw_file_lock(pfile, F_WRLCK, 5)) < 0) {
  5454. +        err = errno;
  5455. +        fprintf(stderr, "%s: Failed to lock password file %s.\n",
  5456. +            argv[0], pfile);
  5457. +        fclose(fp);
  5458. +        errno = err;
  5459. +        perror(argv[0]);
  5460. +        exit(err);
  5461. +    }
  5462. +    /* Get the smb passwd entry for this user */
  5463. +    smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd, 
  5464. +                                    &got_valid_nt_entry, &seekpos);
  5465. +    if (smb_pwent == NULL) {
  5466. +        fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
  5467. +            argv[0], pwd->pw_name, pfile);
  5468. +        fclose(fp);
  5469. +        pw_file_unlock(lockfd);
  5470. +        exit(1);
  5471. +    }
  5472. +    /* If we are root we don't need to check the old password. */
  5473. +    if (real_uid != 0) {
  5474. +        if ((valid_old_pwd == False) || (smb_pwent->smb_passwd == NULL)) {
  5475. +            fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
  5476. +            fclose(fp);
  5477. +            pw_file_unlock(lockfd);
  5478. +            exit(1);
  5479. +        }
  5480. +        /* Check the old Lanman password */
  5481. +        if (memcmp(old_p16, smb_pwent->smb_passwd, 16)) {
  5482. +            fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  5483. +            fclose(fp);
  5484. +            pw_file_unlock(lockfd);
  5485. +            exit(1);
  5486. +        }
  5487. +        /* Check the NT password if it exists */
  5488. +        if (smb_pwent->smb_nt_passwd != NULL) {
  5489. +            if (memcmp(old_nt_p16, smb_pwent->smb_nt_passwd, 16)) {
  5490. +                fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  5491. +                fclose(fp);
  5492. +                pw_file_unlock(lockfd);
  5493. +                exit(1);
  5494. +            }
  5495. +        }
  5496. +    }
  5497. +    /*
  5498. +     * If we get here either we were root or the old password checked out
  5499. +     * ok.
  5500. +     */
  5501. +    /* Create the 32 byte representation of the new p16 */
  5502. +    for (i = 0; i < 16; i++) {
  5503. +        sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]);
  5504. +    }
  5505. +    if(got_valid_nt_entry) {
  5506. +        /* Add on the NT md4 hash */
  5507. +        ascii_p16[32] = ':';
  5508. +        for (i = 0; i < 16; i++) {
  5509. +               sprintf(&ascii_p16[(i * 2)+33], "%02X", (uchar) new_nt_p16[i]);
  5510. +        }
  5511.      }
  5512. -    /* Check the old passwd (if there was one). */
  5513. -    if(smb_pwent->smb_passwd != NULL) {
  5514. -      if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
  5515. -    fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
  5516. +    /*
  5517. +     * Do an atomic write into the file at the position defined by
  5518. +     * seekpos.
  5519. +     */
  5520. +    pwfd = fileno(fp);
  5521. +    ret = lseek(pwfd, seekpos - 1, SEEK_SET);
  5522. +    if (ret != seekpos - 1) {
  5523. +        err = errno;
  5524. +        fprintf(stderr, "%s: seek fail on file %s.\n",
  5525. +            argv[0], pfile);
  5526. +        fclose(fp);
  5527. +        errno = err;
  5528. +        perror(argv[0]);
  5529. +        pw_file_unlock(lockfd);
  5530. +        exit(1);
  5531. +    }
  5532. +    /* Sanity check - ensure the character is a ':' */
  5533. +    if (read(pwfd, &c, 1) != 1) {
  5534. +        err = errno;
  5535. +        fprintf(stderr, "%s: read fail on file %s.\n",
  5536. +            argv[0], pfile);
  5537. +        fclose(fp);
  5538. +        errno = err;
  5539. +        perror(argv[0]);
  5540. +        pw_file_unlock(lockfd);
  5541. +        exit(1);
  5542. +    }
  5543. +    if (c != ':') {
  5544. +        fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
  5545. +            argv[0], pfile);
  5546. +        fclose(fp);
  5547. +        pw_file_unlock(lockfd);
  5548. +        exit(1);
  5549. +    }
  5550. +    writelen = (got_valid_nt_entry) ? 65 : 32;
  5551. +    if (write(pwfd, ascii_p16, writelen) != writelen) {
  5552. +        err = errno;
  5553. +        fprintf(stderr, "%s: write fail in file %s.\n",
  5554. +            argv[0], pfile);
  5555. +        fclose(fp);
  5556. +        errno = err;
  5557. +        perror(argv[0]);
  5558. +        pw_file_unlock(lockfd);
  5559. +        exit(err);
  5560. +    }
  5561.      fclose(fp);
  5562.      pw_file_unlock(lockfd);
  5563. -    exit(1);
  5564. -      }
  5565. -    }
  5566. -  }
  5567. -  /* If we get here either we were root or the old password
  5568. -     checked out ok. */
  5569. -  /* Create the 32 byte representation of the new p16 */
  5570. -  for(i = 0; i < 16; i++) {
  5571. -    sprintf(&ascii_p16[i*2], "%02X", (uchar)new_p16[i]);
  5572. -  }
  5573. -  /* Do an atomic write into the file at the position
  5574. -     defined by seekpos. */
  5575. -  pwfd = fileno(fp);
  5576. -  ret = lseek(pwfd, seekpos - 1, SEEK_SET);
  5577. -  if(ret != seekpos -1) {
  5578. -    err = errno;
  5579. -    fprintf(stderr, "%s: seek fail on file %s.\n", 
  5580. -        argv[0], pfile);
  5581. -    fclose(fp);
  5582. -    errno = err;
  5583. -    perror(argv[0]);
  5584. -    pw_file_unlock(lockfd);
  5585. -    exit(1);
  5586. -  }
  5587. -  /* Sanity check - ensure the character is a ':' */
  5588. -  if(read(pwfd,&c,1) != 1) {
  5589. -    err = errno;
  5590. -    fprintf(stderr, "%s: read fail on file %s.\n", 
  5591. -        argv[0], pfile);
  5592. -    fclose(fp);
  5593. -    errno = err;
  5594. -    perror(argv[0]);
  5595. -    pw_file_unlock(lockfd);
  5596. -    exit(1);
  5597. -  }
  5598. -  if(c != ':') {
  5599. -    fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
  5600. -        argv[0], pfile);
  5601. -    fclose(fp);
  5602. -    pw_file_unlock(lockfd);
  5603. -    exit(1);
  5604. -  }
  5605. -  if(write(pwfd,ascii_p16,32)!=32) {
  5606. -    err = errno;
  5607. -    fprintf(stderr, "%s: write fail in file %s.\n", 
  5608. -        argv[0], pfile);
  5609. -    fclose(fp);
  5610. -    errno = err;
  5611. -    perror(argv[0]);
  5612. -    pw_file_unlock(lockfd);
  5613. -    exit(err);
  5614. -  }
  5615. -  fclose(fp);
  5616. -  pw_file_unlock(lockfd);
  5617. -  printf("Password changed\n");
  5618. -  return 0;
  5619. +    printf("Password changed\n");
  5620. +    return 0;
  5621.  }
  5622.  
  5623.  #else
  5624.  
  5625.  #include "includes.h"
  5626.  
  5627. -int main(int argc, char **argv)
  5628. +int 
  5629. +main(int argc, char **argv)
  5630.  {
  5631. -  printf("smb password encryption not selected in Makefile\n");
  5632. -  return 0;
  5633. +    printf("smb password encryption not selected in Makefile\n");
  5634. +    return 0;
  5635.  }
  5636.  #endif
  5637. -
  5638. -
  5639. diff -u -r --new-file last-version/source/status.c samba-1.9.14p3/source/status.c
  5640. --- last-version/source/status.c    Sat Nov  4 23:19:07 1995
  5641. +++ samba-1.9.14p3/source/status.c    Mon Nov  6 15:55:40 1995
  5642. @@ -117,7 +117,8 @@
  5643.      else
  5644.        printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
  5645.           crec.name,uidtoname(crec.uid),gidtoname(crec.gid),crec.pid,
  5646. -         crec.machine,crec.addr,asctime(LocalTime(&crec.start,0)));
  5647. +         crec.machine,crec.addr,
  5648. +         asctime(LocalTime(&crec.start,GMT_TO_LOCAL)));
  5649.        }
  5650.      }
  5651.    fclose(f);
  5652. diff -u -r --new-file last-version/source/trans2.c samba-1.9.14p3/source/trans2.c
  5653. --- last-version/source/trans2.c    Sat Nov  4 20:29:20 1995
  5654. +++ samba-1.9.14p3/source/trans2.c    Tue Nov  7 13:59:36 1995
  5655. @@ -163,7 +163,7 @@
  5656.  #if 0
  5657.    BOOL return_additional_info = BITSETW(params,0);
  5658.    int16 open_sattr = SVAL(params, 4);
  5659. -  int32 open_time = IVAL(params,8);
  5660. +  time_t open_time = make_unix_date3(params+8);
  5661.  #endif
  5662.    int16 open_ofun = SVAL(params,12);
  5663.    int32 open_size = IVAL(params,14);
  5664. @@ -348,7 +348,6 @@
  5665.  
  5666.  #ifdef MANGLE_LONG_FILENAMES
  5667.    {
  5668. -    fstring fname2;
  5669.      BOOL illegal = False;
  5670.      int i;
  5671.      int l = strlen(fname);
  5672. @@ -357,8 +356,7 @@
  5673.      illegal = True;
  5674.      break;
  5675.        }
  5676. -    name_convert(fname2,fname,illegal,SNUM(cnum));
  5677. -    strcpy(fname,fname2);
  5678. +    name_map_mangle(fname,illegal,SNUM(cnum));
  5679.    }
  5680.  #endif
  5681.  
  5682. @@ -445,13 +443,15 @@
  5683.        SIVAL(p,0,mode); p += 4;
  5684.        SIVAL(p,0,strlen(fname)); p += 4;
  5685.        SIVAL(p,0,0); p += 4;
  5686. -      if (!is_8_3(fname))
  5687. -    name_convert(p+2,fname,True,SNUM(cnum));
  5688. -      else
  5689. +      if (!is_8_3(fname)) {
  5690. +    strcpy(p+2,unix2dos_format(fname,False));
  5691. +    name_map_mangle(p+2,True,SNUM(cnum));
  5692. +      } else
  5693.      *(p+2) = 0;
  5694.        strupper(p+2);
  5695.        SSVAL(p,0,strlen(p+2));
  5696.        p += 2 + 24;
  5697. +      /* name_ptr = p;  */
  5698.        strcpy(p,fname); p += strlen(p);
  5699.        break;
  5700.  
  5701. @@ -1208,8 +1208,8 @@
  5702.    switch (info_level)
  5703.      {
  5704.      case 1:
  5705. -      tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess,False);
  5706. -      tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite,False);
  5707. +      tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
  5708. +      tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
  5709.        mode = SVAL(pdata,l1_attrFile);
  5710.        size = IVAL(pdata,l1_cbFile);
  5711.        break;
  5712. @@ -1217,15 +1217,15 @@
  5713.      case 2:
  5714.        if(IVAL(pdata,l2_cbList) || total_data>32)
  5715.      return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
  5716. -      tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess,False);
  5717. -      tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite,False);
  5718. +      tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
  5719. +      tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
  5720.        mode = SVAL(pdata,l1_attrFile);
  5721.        size = IVAL(pdata,l1_cbFile);
  5722.        break;
  5723.  
  5724.      case 3:
  5725. -      tvs.actime = make_unix_date2(pdata+8,False);
  5726. -      tvs.modtime = make_unix_date2(pdata+12,False);
  5727. +      tvs.actime = make_unix_date2(pdata+8);
  5728. +      tvs.modtime = make_unix_date2(pdata+12);
  5729.        size = IVAL(pdata,16);
  5730.        mode = IVAL(pdata,24);
  5731.        break;
  5732. @@ -1233,8 +1233,8 @@
  5733.      case 4:
  5734.        if (IVAL(pdata,28) != 0 || total_data>36)
  5735.      return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));    
  5736. -      tvs.actime = make_unix_date2(pdata+8,False);
  5737. -      tvs.modtime = make_unix_date2(pdata+12,False);
  5738. +      tvs.actime = make_unix_date2(pdata+8);
  5739. +      tvs.modtime = make_unix_date2(pdata+12);
  5740.        size = IVAL(pdata,16);
  5741.        mode = IVAL(pdata,24);
  5742.        break;
  5743. diff -u -r --new-file last-version/source/updatesmbpasswd.sh samba-1.9.14p3/source/updatesmbpasswd.sh
  5744. --- last-version/source/updatesmbpasswd.sh    Thu Jan  1 10:00:00 1970
  5745. +++ samba-1.9.14p3/source/updatesmbpasswd.sh    Sun Nov  5 15:47:33 1995
  5746. @@ -0,0 +1,14 @@
  5747. +#!/bin/sh
  5748. +nawk 'BEGIN {FS=":"} 
  5749. +{
  5750. +    if( $0 ~ "^#" ) {
  5751. +        print $0
  5752. +    } else if( (length($4) == 32) && (($4 ~ "^[0-9A-F]*$") || ($4 ~ "^[X]*$") || ( $4 ~ "^[*]*$"))) {
  5753. +        print $0
  5754. +    } else {
  5755. +        printf( "%s:%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", $1, $2, $3);
  5756. +        for(i = 4; i <= NF; i++)
  5757. +            printf("%s:", $i)
  5758. +        printf("\n")
  5759. +    }
  5760. +}'
  5761. diff -u -r --new-file last-version/source/util.c samba-1.9.14p3/source/util.c
  5762. --- last-version/source/util.c    Sat Nov  4 22:14:20 1995
  5763. +++ samba-1.9.14p3/source/util.c    Tue Nov  7 18:24:45 1995
  5764. @@ -288,6 +288,11 @@
  5765.    tm_local = *(localtime(&t));
  5766.  
  5767.    timediff = mktime(&tm_utc) - mktime(&tm_local);
  5768. +
  5769. +  if (serverzone == 0) {
  5770. +    serverzone = timediff - DSTDiff(t);
  5771. +    DEBUG(4,("Serverzone is %d\n",serverzone));
  5772. +  }
  5773.  }
  5774.  
  5775.  
  5776. @@ -365,20 +370,10 @@
  5777.  int TimeDiff(time_t t)
  5778.  {
  5779.    static BOOL initialised = False;
  5780. -  if (!initialised) {TimeInit(); initialised=True;}
  5781. +  if (!initialised) {initialised=True; TimeInit();}
  5782.    return(timediff - DSTDiff(t));
  5783.  }
  5784.  
  5785. -
  5786. -/****************************************************************************
  5787. -try to optimise the timelocal call, it can be quite expenive on some machines
  5788. -****************************************************************************/
  5789. -static time_t TimeLocal(struct tm *tm,int timemul)
  5790. -{
  5791. -  time_t ret = mktime(tm);
  5792. -  return(ret + timemul * TimeDiff(ret));
  5793. -}
  5794. -
  5795.  /****************************************************************************
  5796.  try to optimise the localtime call, it can be quite expenive on some machines
  5797.  timemul is normally LOCAL_TO_GMT, GMT_TO_LOCAL or 0
  5798. @@ -387,7 +382,8 @@
  5799.  {
  5800.    time_t t2 = *t;
  5801.  
  5802. -  t2 += timemul * TimeDiff(t2);
  5803. +  if (timemul)
  5804. +    t2 += timemul * TimeDiff(t2);
  5805.  
  5806.    return(gmtime(&t2));
  5807.  }
  5808. @@ -680,6 +676,15 @@
  5809.  char *StrCpy(char *dest,char *src)
  5810.  {
  5811.    char *d = dest;
  5812. +
  5813. +#if AJT
  5814. +  /* I don't want to get lazy with these ... */
  5815. +  if (!dest || !src) {
  5816. +    DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
  5817. +    ajt_panic();
  5818. +  }
  5819. +#endif
  5820. +
  5821.    if (!dest) return(NULL);
  5822.    if (!src) {
  5823.      *dest = 0;
  5824. @@ -830,14 +835,15 @@
  5825.  /*******************************************************************
  5826.    check if a directory exists
  5827.  ********************************************************************/
  5828. -BOOL directory_exist(char *dname)
  5829. +BOOL directory_exist(char *dname,struct stat *st)
  5830.  {
  5831. -  struct stat st;
  5832. +  struct stat st2;
  5833. +  if (!st) st = &st2;
  5834.  
  5835. -  if (sys_stat(dname,&st) != 0) 
  5836. +  if (sys_stat(dname,st) != 0) 
  5837.      return(False);
  5838.  
  5839. -  return(S_ISDIR(st.st_mode));
  5840. +  return(S_ISDIR(st->st_mode));
  5841.  }
  5842.  
  5843.  /*******************************************************************
  5844. @@ -851,6 +857,16 @@
  5845.    return(buf.st_size);
  5846.  }
  5847.  
  5848. +/****************************************************************************
  5849. +check if it's a null mtime
  5850. +****************************************************************************/
  5851. +static BOOL null_mtime(time_t mtime)
  5852. +{
  5853. +  if (mtime == 0 || mtime == 0xFFFFFFFF)
  5854. +    return(True);
  5855. +  return(False);
  5856. +}
  5857. +
  5858.  /*******************************************************************
  5859.    create a 16 bit dos packed date
  5860.  ********************************************************************/
  5861. @@ -875,6 +891,7 @@
  5862.  
  5863.  /*******************************************************************
  5864.    create a 32 bit dos packed date/time from some parameters
  5865. +  This takes a GMT time and returns a packed localtime structure
  5866.  ********************************************************************/
  5867.  static uint32 make_dos_date(time_t unixdate)
  5868.  {
  5869. @@ -891,6 +908,7 @@
  5870.  
  5871.  /*******************************************************************
  5872.  put a dos date into a buffer (time/date format)
  5873. +This takes GMT time and puts local time in the buffer
  5874.  ********************************************************************/
  5875.  void put_dos_date(char *buf,int offset,time_t unixdate)
  5876.  {
  5877. @@ -900,6 +918,7 @@
  5878.  
  5879.  /*******************************************************************
  5880.  put a dos date into a buffer (date/time format)
  5881. +This takes GMT time and puts local time in the buffer
  5882.  ********************************************************************/
  5883.  void put_dos_date2(char *buf,int offset,time_t unixdate)
  5884.  {
  5885. @@ -908,6 +927,17 @@
  5886.    SIVAL(buf,offset,x);
  5887.  }
  5888.  
  5889. +/*******************************************************************
  5890. +put a dos 32 bit "unix like" date into a buffer. This routine takes
  5891. +GMT and converts it to LOCAL time before putting it (most SMBs assume
  5892. +localtime for this sort of date)
  5893. +********************************************************************/
  5894. +void put_dos_date3(char *buf,int offset,time_t unixdate)
  5895. +{
  5896. +  if (!null_mtime(unixdate))
  5897. +    unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
  5898. +  SIVAL(buf,offset,unixdate);
  5899. +}
  5900.  
  5901.  /*******************************************************************
  5902.    interpret a 32 bit dos packed date/time to some parameters
  5903. @@ -928,9 +958,10 @@
  5904.  }
  5905.  
  5906.  /*******************************************************************
  5907. -  create a unix date from a dos date
  5908. +  create a unix date (int GMT) from a dos date (which is actually in
  5909. +  localtime)
  5910.  ********************************************************************/
  5911. -time_t make_unix_date(void *date_ptr,BOOL add_dst)
  5912. +time_t make_unix_date(void *date_ptr)
  5913.  {
  5914.    uint32 dos_date=0;
  5915.    struct tm t;
  5916. @@ -945,17 +976,18 @@
  5917.    t.tm_wday = 1;
  5918.    t.tm_yday = 1;
  5919.    t.tm_isdst = -1;
  5920. -
  5921. -  ret = TimeLocal(&t,GMT_TO_LOCAL);
  5922. +  
  5923. +  /* mktime() also does the local to GMT time conversion for us. XXXXX
  5924. +     Do all unixes do this the same?? */
  5925. +  ret = mktime(&t);
  5926.  
  5927. -  if (add_dst) ret += DSTDiff(ret);
  5928.    return(ret);
  5929.  }
  5930.  
  5931.  /*******************************************************************
  5932. -  create a unix date from a dos date
  5933. +like make_unix_date() but the words are reversed
  5934.  ********************************************************************/
  5935. -time_t make_unix_date2(void *date_ptr,BOOL add_dst)
  5936. +time_t make_unix_date2(void *date_ptr)
  5937.  {
  5938.    uint32 x,x2;
  5939.  
  5940. @@ -963,9 +995,20 @@
  5941.    x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
  5942.    SIVAL(&x,0,x2);
  5943.  
  5944. -  return(make_unix_date((void *)&x,add_dst));
  5945. +  return(make_unix_date((void *)&x));
  5946.  }
  5947.  
  5948. +/*******************************************************************
  5949. +  create a unix GMT date from a dos date in 32 bit "unix like" format
  5950. +these generally arrive as localtimes, with corresponding DST
  5951. +********************************************************************/
  5952. +time_t make_unix_date3(void *date_ptr)
  5953. +{
  5954. +  time_t t = IVAL(date_ptr,0);
  5955. +  if (!null_mtime(t))
  5956. +    t += LOCAL_TO_GMT*TimeDiff(t);
  5957. +  return(t);
  5958. +}
  5959.  
  5960.  /*******************************************************************
  5961.  return a string representing an attribute for a file
  5962. @@ -988,13 +1031,24 @@
  5963.  
  5964.  
  5965.  /*******************************************************************
  5966. +  case insensitive string compararison
  5967. +********************************************************************/
  5968. +int StrCaseCmp(char *s, char *t)
  5969. +{
  5970. +  for (; tolower(*s) == tolower(*t); ++s, ++t)
  5971. +    if (!*s) return 0;
  5972. +
  5973. +  return tolower(*s) - tolower(*t);
  5974. +}
  5975. +
  5976. +/*******************************************************************
  5977.    compare 2 strings 
  5978.  ********************************************************************/
  5979.  BOOL strequal(char *s1,char *s2)
  5980.  {
  5981.    if (!s1 || !s2) return(False);
  5982.    
  5983. -  return(strcasecmp(s1,s2)==0);
  5984. +  return(StrCaseCmp(s1,s2)==0);
  5985.  }
  5986.  
  5987.  /*******************************************************************
  5988. @@ -1877,10 +1931,6 @@
  5989.  ****************************************************************************/
  5990.  int read_udp_socket(int fd,char *buf,int len)
  5991.  {
  5992. -  /* #define NORECVFROM */
  5993. -#ifdef NORECVFROM
  5994. -  return(read_data(fd,buf,len));
  5995. -#else
  5996.    int ret;
  5997.    struct sockaddr sock;
  5998.    int socklen;
  5999. @@ -1901,7 +1951,6 @@
  6000.      DEBUG(3,("read %d bytes\n",ret));
  6001.  
  6002.    return(ret);
  6003. -#endif
  6004.  }
  6005.  
  6006.  /****************************************************************************
  6007. @@ -2539,7 +2588,7 @@
  6008.  /****************************************************************************
  6009.  send a single packet to a port on another machine
  6010.  ****************************************************************************/
  6011. -BOOL send_packet(char *buf,int len,struct in_addr *ip,int port,int type)
  6012. +BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type)
  6013.  {
  6014.    BOOL ret;
  6015.    int out_fd;
  6016. @@ -2620,7 +2669,7 @@
  6017.      if (strcmp(tok,s) == 0)
  6018.        return(True);
  6019.        } else {
  6020. -    if (strcasecmp(tok,s) == 0)
  6021. +    if (StrCaseCmp(tok,s) == 0)
  6022.        return(True);
  6023.        }
  6024.      }
  6025. @@ -3261,18 +3310,6 @@
  6026.    return(ret);
  6027.  }
  6028.  
  6029. -
  6030. -/****************************************************************************
  6031. -check if it's a null mtime
  6032. -****************************************************************************/
  6033. -static BOOL null_mtime(time_t mtime)
  6034. -{
  6035. -  if (mtime == 0 || mtime == 0xFFFFFFFF)
  6036. -    return(True);
  6037. -  return(False);
  6038. -}
  6039. -
  6040. -
  6041.  /****************************************************************************
  6042.  set the time on a file
  6043.  ****************************************************************************/
  6044. @@ -3612,11 +3649,16 @@
  6045.    return(res);
  6046.  }
  6047.  
  6048. -#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60 - (3.0*24*60*60 + 6.0*60*60))
  6049. +#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
  6050.  
  6051.  /****************************************************************************
  6052.  interpret an 8 byte "filetime" structure to a time_t
  6053.  It's originally in "100ns units since jan 1st 1601"
  6054. +
  6055. +It appears to be kludge-GMT (at least for file listings). This means
  6056. +its the GMT you get by taking a localtime and adding the
  6057. +serverzone. This is NOT the same as GMT in some cases. This routine
  6058. +converts this to real GMT.
  6059.  ****************************************************************************/
  6060.  time_t interpret_long_date(char *p)
  6061.  {
  6062. @@ -3635,30 +3677,42 @@
  6063.    /* now adjust by 369 years to make the secs since 1970 */
  6064.    d -= TIME_FIXUP_CONSTANT;
  6065.  
  6066. +  if (d>=MAXINT)
  6067. +    return(0);
  6068. +
  6069.    ret = (time_t)(d+0.5);
  6070.  
  6071. +  /* this takes us from kludge-GMT to real GMT */
  6072. +  ret += TimeDiff(ret) - serverzone;
  6073. +
  6074.    return(ret);
  6075.  }
  6076.  
  6077.  
  6078.  /****************************************************************************
  6079.  put a 8 byte filetime from a time_t
  6080. +This takes real GMT as input and converts to kludge-GMT
  6081.  ****************************************************************************/
  6082.  void put_long_date(char *p,time_t t)
  6083.  {
  6084.    uint32 tlow,thigh;
  6085. -  double d = (double) (t);
  6086. +  double d;
  6087.  
  6088.    if (t==0) {
  6089.      SIVAL(p,0,0); SIVAL(p,4,0);
  6090.      return;
  6091.    }
  6092.  
  6093. +  /* this converts GMT to kludge-GMT */
  6094. +  t -= TimeDiff(t) - serverzone; 
  6095. +
  6096. +  d = (double) (t);
  6097. +
  6098.    d += TIME_FIXUP_CONSTANT;
  6099.  
  6100. -  d /= 1.0e-7;
  6101. +  d *= 1.0e7;
  6102.  
  6103. -  thigh = (uint32)(d / (4.0*(double)(1<<30)));
  6104. +  thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
  6105.    tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
  6106.  
  6107.    SIVAL(p,0,tlow);
  6108. @@ -3800,7 +3854,7 @@
  6109.  #ifdef LINUX
  6110.    fstring s;
  6111.    sprintf(s,"/proc/%d",pid);
  6112. -  return(directory_exist(s));
  6113. +  return(directory_exist(s,NULL));
  6114.  #else
  6115.    {
  6116.      static BOOL tested=False;
  6117. @@ -4137,8 +4191,8 @@
  6118.  
  6119.  int
  6120.  rename (zfrom, zto)
  6121. -     char const  *zfrom;
  6122. -     char const *zto;
  6123. +     char *zfrom;
  6124. +     char *zto;
  6125.  {
  6126.    if (link (zfrom, zto) < 0)
  6127.      {
  6128. @@ -4151,19 +4205,6 @@
  6129.    return unlink (zfrom);
  6130.  }
  6131.  
  6132. -#endif
  6133. -
  6134. -#ifdef NOSTRCASECMP
  6135. -/*******************************************************************
  6136. -  case insensitive string compararison
  6137. -********************************************************************/
  6138. -int strcasecmp(char *s, char *t)
  6139. -{
  6140. -  for (; tolower(*s) == tolower(*t); ++s, ++t)
  6141. -    if (!*s) return 0;
  6142. -
  6143. -  return tolower(*s) - tolower(*t);
  6144. -}
  6145.  #endif
  6146.  
  6147.  #if WRAP_MEMCPY
  6148. diff -u -r --new-file last-version/source/version.h samba-1.9.14p3/source/version.h
  6149. --- last-version/source/version.h    Sat Nov  4 23:21:27 1995
  6150. +++ samba-1.9.14p3/source/version.h    Tue Nov  7 23:00:33 1995
  6151. @@ -1 +1 @@
  6152. -#define VERSION "1.9.14p2"
  6153. +#define VERSION "1.9.14p3"
  6154.